Apologies, I’m new to Django, so this might be super obvious.
I’m trying to test the user change-password functionality on my webapp.
I can see that the password has successfully changed when I login as admin and look at the relevant user-id (the redacted salt and hash values both change). However, I’m unable to login with the new user credentials (username and password mismatch). The password encryption algorithm hasn’t changed (pbkdf2_sha256) - so I’m not sure where it’s going wrong.
Below is a snippet of the relevant part of the code:
uid = force_str(urlsafe_base64_decode(uidb64))
user = MyUser.objects.get(pk=uid)
# ...
form = SetPasswordForm(user,request.POST)
if form.is_valid():
user = form.save(commit=False)
print('user = ' + str(user))
print(form.cleaned_data.get("new_password1"))
user.save()
The print statements above show exactly what I was expecting (i.e. the test username and the new password are printed).
Is this something to do with me creating a new user model MyUser rather than the Django out of the box? Since SetPasswordForm takes user as an argument, I assumed all would be well.
Any help greatly appreciated. Also, if anyone knows of any solid examples I could look at of the Django authentication used in practice, I’d love to take a look. The docs are a bit dry in this area.
To add to @addwebsolution’s answer above, the best examples of Django authentication in practice would be to look at Django’s own authentication views in django.contrib.auth.views, along with the forms in django.contrib.auth.forms.
Thanks for that @addwebsolution and @KenWhitesell. I’ll have a go doing set_password explicitly.
But - how is that different to what SetPasswordForm is doing? According to the source code it’s just doing set_password anyway. Am I missing something?
def save(self, commit=True):
self.user.set_password(self.cleaned_data['new_password1'])
if commit:
self.user.save()
return self.user
is creating an instance of the SetPasswordForm object. It’s not, of its own, doing anything with the data other than populating the object with what was submitted from the browser.
It’s the line:
that should be causing the save method to update the password.
Now, the key point that I missed was:
By this, you’re trying to use a custom user model?
Yes - the Django tutorial I was following suggested that it’s always good practice to create your own user model (but didn’t really explain why).
I have set AUTH_USER_MODEL in settings.py.
To be clear - I can create new users and login fine via this same user model, it’s only when I try to save a new password that it falls over. This is why I was scratching my head.