santiagobasulto
santiagobasulto

Reputation: 11686

Django: How to destroy user session after a password reset/change?

i've recently implemented a simple change password view in my django project. The thing is that the old session should be destroyed for security reasons. What's the best way of doing this without asking the user to log in again.

I think i could just logout/login him/her, something like this:

from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout

@login_required
def change_password(request):
  # My stuff
  request.user.set_password(new_password)
  request.user.save()
  # I need this:
  logout(request)
  login(request,request.user)

But i think this is not the best idea. What do you think?

Is there another way to do this?

Am I missing something? (I mean, is this secure)

Upvotes: 6

Views: 7982

Answers (4)

hwjp
hwjp

Reputation: 16071

I just found out that this is now a built-in feature of Django, and has been since 1.7:

https://docs.djangoproject.com/en/1.7/topics/auth/default/#session-invalidation-on-password-change

Essentially, all sessions now include a hash of the users' password, so if the user ever changes their password, all their existing sessions are automatically invalidated.

So, the short answer to your question is: upgrade django.

One possibly undesirable side effect of this change is that, by default, a user ends up having to log in again as soon as they change their password. So you probably actually want the current user session to stay logged in. See the docs already linked, Django's built-in views for password change do that for you default, or you can manually call a function called update_session_auth_hash

Upvotes: 2

Albert Tugushev
Albert Tugushev

Reputation: 1712

Take a look at this app https://github.com/atugushev/django-password-session. This package makes invalidated all sessions (except a current session) after change a password.

Also this feature finally was implemented in Django 1.7. See: https://docs.djangoproject.com/en/dev/topics/auth/default/#session-invalidation-on-password-change

Upvotes: 3

dani herrera
dani herrera

Reputation: 51665

I don't understand whats are these security reasons that forces to reset session. But, the way is:

@login_required
def change_password(request):
  request.user.set_password(new_password)
  request.user.save()
  username = request.user.username
  logout(request)
  user = authenticate(username=username, password=new_password) #<-- here!!
  if user is not None:
      login(request,user)
  else:
      #raise your exception

you should authenticate before login. Quoting doc:

Calling authenticate() first When you're manually logging a user in, you must call authenticate() before you call login(). authenticate() sets an attribute on the User noting which authentication backend successfully authenticated that user (see the backends documentation for details), and this information is needed later during the login process.

Upvotes: 1

Timmy O&#39;Mahony
Timmy O&#39;Mahony

Reputation: 53981

django clears the session on logout so you will be fine:

https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.logout

When you call logout(), the session data for the current request is completely cleaned out. All existing data is removed. This is to prevent another person from using the same Web browser to log in and have access to the previous user's session data.

Upvotes: 1

Related Questions