如何在 Django 中修改用户密码后保持会话不丢失
技术百科
碧海醫心
发布时间:2026-01-01
浏览: 次 django 默认会在用户密码变更后自动失效旧会话,导致用户登出;解决方法是调用 `update_session_auth_hash()` 保留当前登录状态。
在 Django 中,当用户密码被修改(例如通过自定义视图 psswdReset),框架出于安全考虑会主动使所有基于旧密码的会话失效——这是默认行为,并非 Bug。其原理在于:Django 的认证中间件会比对当前 session 中存储的哈希签名与用户 password 字段的哈希值。一旦 user.password 被直接更新(如 user.password = make_password(...)),而未同步更新 session 的认证标识,下次请求时 AuthenticationMiddleware 将检测到不一致,强制将 request.user 置为 AnonymousUser,即“会话被冲刷”。
您当前的代码存在两个关键问题:
- 未调用 update_session_auth_hash():这是最核心的修复点;
- 手动赋值 user.password 并保存:虽可行,但绕过了 Django 用户模型的安全更新逻辑,易遗漏信号或钩子。
✅ 正确做法如下(推荐使用 set_password() + update_session_auth_hash()):
from django.contrib.auth import update_session_auth_hash
from django.contrib import messages
def psswdReset(request):
if request.method == 'POST':
new_psswd = request.POST.get('new_psswd')
psswd = request.POST.get('psswd')
# 验证原密码正确性
if not request.user.check_password(psswd):
messages.error(request, 'Current password is incorrect.')
return render(request, 'User/userPsswdReset.html')
# 安全设置新密码(自动哈希)
request.user.set_password(new_psswd)
request.user.save()
# ? 关键:更新 session 认证哈希,防止登出
update_session_auth_hash(request, request
.user)
messages.success(request, 'Password changed successfully!')
return render(request, 'User/userPsswdReset.html')
return render(request, 'User/userPsswdReset.html')? 注意事项:
- update_session_auth_hash(request, user) 必须在 user.save() 之后调用,且 user 必须是当前已认证的用户实例(通常为 request.user);
- 不要使用 check_password(psswd, request.user.password) 手动比对——应直接调用 request.user.check_password(),它更安全且兼容自定义密码 hasher;
- 若使用 CustomUser 模型,请确保其继承自 AbstractBaseUser 或 AbstractUser,并正确实现了 set_password() 方法;
- 该机制仅影响当前用户的活跃会话,其他设备/浏览器的会话仍会被安全地注销(符合预期)。
? 总结:密码修改后会话丢失是 Django 的主动安全防护机制,而非缺陷。只需在保存新密码后调用 update_session_auth_hash(),即可在保障安全性的同时提供无缝的用户体验。
# 解决方法
# 安全防护
# 浏览器
# word
# go
# html
# session
# 中间件
# django
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 短链接还原php提示内存不足_调整PHP内存限制设
- Python高性能计算项目教程_NumPyCyth
- Win11怎么更改任务栏颜色_Windows11个
- php增删改查需要哪些扩展_开启mysqli或pd
- c# await 一个已经完成的Task会发生什么
- Win11怎么更改管理员名字 Win11修改账户名
- Win11快速助手怎么用_Win11远程协助连接教
- 如何有效拦截拼接式恶意域名的垃圾信息
- Dapper的Execute方法的返回值是什么意思
- php修改数据怎么改富文本_update更新htm
- 如何在Golang中实现邮件发送功能_Golang
- windows系统如何安装cab更新补丁_wind
- Linux怎么查找死循环进程_Linux系统负载分
- PHP的Workerman对架构扩展有啥帮助_应用
- 如何使用Golang理解结构体指针方法接收者_Go
- 如何在Golang中验证模块完整性_Golangg
- 如何在包含多值的列中精准搜索指定演员?
- c++如何用AFL++进行模糊测试 c++ Fuz
- 作用域操作符会影响性能吗_php静态调用性能分析【
- 如何在Golang中实现WebSocket广播_使
- 如何在Golang中指定模块版本_使用go.mod
- Python 模块的 __name__ 属性如何由
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- Windows 11如何查看系统激活密钥_Wind
- PHP cURL GET请求:正确设置请求头与身份
- c# 在ASP.NET Core中管理和取消后台任
- C++如何获取CPU核心数?(std::threa
- Win11怎么设置默认浏览器Chrome_Wind
- VSC怎么配置PHP的Xdebug_远程调试设置步
- Windows蓝屏BAD_POOL_HEADER故
- php打包exe后无法写入文件_权限问题解决方法【
- windows 10应用商店区域怎么改_windo
- 如何在Golang中实现服务熔断与限流_Golan
- C#如何在一个XML文件中查找并替换文本内容
- Win11无法安装软件怎么办_Win11解除应用安
- Python集合操作技巧_高效去重解析【教程】
- Django 密码修改后会话失效的解决方案
- 如何使用正则表达式批量替换重复的 *- 模式为固定
- 如何开启Windows的远程服务器管理工具(RSA
- Win11任务栏天气怎么关闭 Win11隐藏天气小
- Python对象生命周期管理_创建销毁说明【指导】
- php与c语言在嵌入式中有何区别_对比两者在硬件控
- phpstudy本地环境mysql忘记密码_重置m
- Python变量绑定机制_引用模型解析【教程】
- 如何在JavaScript中动态拼接PHP的bas
- 如何用正则与预处理结合精准拦截拼接式垃圾域名
- Win11开机速度慢怎么优化_Win11系统启动加
- Win11怎么关闭触摸屏_禁用Win11笔记本触摸
- Win11键盘快捷键大全_Windows 11常用

.user)
messages.success(request, 'Password changed successfully!')
return render(request, 'User/userPsswdReset.html')
return render(request, 'User/userPsswdReset.html')
QQ客服