Update: I've inserted this page because a fellow student pointed out there is a bug in the UserProfileSerializer (thanks Avi!)
(This is a temporary insert until we can update the videos appropriately)
Issue
If a user updates their profile, the password field is stored in cleartext, and they are unable to login.
Cause
This is because we need to override the default behaviour of Django REST Frameworks ModelSerializer to hash the users password when updating.
Fix
To fix the issue, add the below method to the UserProfileSerializer
def update(self, instance, validated_data):
"""Handle updating user account"""
if 'password' in validated_data:
password = validated_data.pop('password')
instance.set_password(password)
return super().update(instance, validated_data)The final serializers.py file will look like this: https://github.com/LondonAppDev/profiles-rest-api/blob/master/profiles_api/serializers.py#L34
Explanation
The default update logic for the Django REST Framework (DRF) ModelSerializer code will take whatever fields are provided (in our case: email, name, password) and pass them directly to the model.
This is fine for the email and name fields, however the password field requires some additional logic to hash the password before saving the update.
Therefore, we override the Django REST Framework's update() method to add this logic to check for the presence password in the validated_data which is passed from DRF when updating an object.
If the field exists, we will "pop" (which means assign the value and remove from the dictionary) the password from the validated data and set it using set_password() (which saves the password as a hash).
Once that's done, we use super().update() to pass the values to the existing DRF update() method, to handle updating the remaining fields.