[Answered ]-Django – revisiting "change password at next login”

1👍

It is generally a good practice to require an authenticated user provide the current password when changing passwords. This protects against the case, even if unlikely, that a logged in user leaves the workstation with an active session and some "evil" user attempts to hijack their account by changing the password.

By requiring the user to enter both the old and new passwords you can also prevent password re-use both on the client and server side. This allows for increased usability for your users since you can warn them and disable submission of the form using JavaScript. By capturing the old and new passwords, you can pass both to the server and verify against re-use similar to the answer provided by warath-coder.

Update

As you’ve mentioned Django saved the hashes and not the actual passwords, and as a further protection the passwords are salted, see the Django docs on how passwords are stored. Because of this, you will not be able to simply compare the hashes. You can test that the old and new passwords match in the clean_new_password1 method of your form using the form data prior to the User object being updated. This can be done by simple comparison or by trying to authenticate with the old password as warath-coder has described.

👤Fiver

1👍

I would do this:

def password_change_signal(sender, instance, **kwargs):
try:
    user = authenticate(username=instance.username, password=instance.password)
    if user is None:  # means auth failed, which means password is not the same as the current password.
        user = User.objects.get(username=instance.username)
        user.set_password(instance.password)
        user.save()
        profile = user.get_profile()
        profile.force_password_change = False
        profile.save()
except User.DoesNotExist:
    pass

basically i try to authenticate the user with the password they supply, and it should fail if the new password is different than the current.

Leave a comment