Django Authentication issue after reseting password

Question:

I am using django 1.8 for my project and I have tried using django.contrib.auth.middleware.SessionAuthenticationMiddleware in middleware to log off the other session after resetting the password. This is fine but the problem I am facing is after resetting it is logging off even that session who changed the password. I want that after resetting the password, the session where we change the password do not get log off. Our user model is inherited from AbstractUser

Asked By: Pramod

||

Answers:

If you use your own view to change password, django gives you ability to update the session after changing password so that the user isn’t logged off.

For that you can use update_session_auth_hash function.

Django’s user_change_password update the session after password change. But for you own custom views, you can use update_session_auth_hash like this:

from django.contrib.auth import update_session_auth_hash

def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)
    else:
        ...

Django docs about session invalidation on password change

Instead of going through all this, you can use django-allauth instead. It is an awesome app and has all sort of authentication functionality to it.

Answered By: v1k45

For some reason the accepted answer didn’t work for me. So I did the obvious… I logged in the user again as usual. Example of a ChangePasswordForm overriding the save() method.

class ChangePasswordForm(models.Form):
    old_password = forms.CharField(widget=forms.PasswordInput())
    password1 = forms.CharField(widget=forms.PasswordInput())
    password2 = forms.CharField(widget=forms.PasswordInput())

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super().__init__(*args, **kwargs)

    def clean(self):
        data = self.cleaned_data
        # authenticate user here (using old_password)
        # check if password1 == password2
        return data

    def save(self, commit=True):
        user = super().save(commit=False)
        if commit:
            user.save()
            login(self.request, user) # HERE IS THE WHOLE THING        

        return user
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.