我最近在我的django项目中实现了一个简单的更改密码视图。问题是出于安全原因应该销毁旧会话。在不要求用户再次登录的情况下,最好的方法是什么。
我想我可以注销/登录他/她,就像这样:
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)
但我认为这不是最好的主意。你觉得怎么样?
还有其他办法吗?
我错过了什么吗? (我的意思是,这是安全的)
答案 0 :(得分:3)
看一下这个应用https://github.com/atugushev/django-password-session。 更改密码后,此程序包使所有会话(当前会话除外)无效。
此功能最终也在Django 1.7中实现。请参阅:https://docs.djangoproject.com/en/dev/topics/auth/default/#session-invalidation-on-password-change
答案 1 :(得分:2)
我刚刚发现这是Django的内置功能,自1.7以来一直在使用:
https://docs.djangoproject.com/en/1.7/topics/auth/default/#session-invalidation-on-password-change
基本上,所有会话现在都包含用户的哈希值'密码,因此如果用户更改了密码,则所有现有会话都将自动失效。
所以,对你的问题的简短回答是:升级django。
此更改的一个可能不良副作用是,默认情况下,用户在更改密码后最终必须再次登录。因此,您可能实际上希望当前用户会话保持登录状态。请参阅已链接的文档,Django的密码更改内置视图为您执行默认操作,或者您可以手动调用一个名为update_session_auth_hash
答案 2 :(得分:1)
django在注销时清除会话,这样你就可以了:
https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.logout
当您调用logout()时,将完全清除当前请求的会话数据。删除所有现有数据。这是为了防止其他人使用同一个Web浏览器登录并访问以前用户的会话数据。
答案 3 :(得分:1)
我不明白这些安全原因会强制重置会话。但是,方式是:
@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
您应该在登录前进行身份验证。引用文档:
首先调用authenticate()当您手动登录用户时, 你必须在调用login()之前调用authenticate()。认证() 在用户上设置属性,注意哪个身份验证后端 成功验证了该用户(请参阅后端文档 有关详细信息),稍后在登录期间需要此信息 过程