如何在 Django 中安全修改用户密码而不使会话失效
技术百科
霞舞
发布时间:2026-01-01
浏览: 次 django 默认在用户密码变更后自动清除其会话,导致用户登出;解决方法是调用 `update_session_auth_hash()` 保留当前登录状态。
在 Django 中,当用户密码被修改(例如通过自定义视图 psswdReset),框架出于安全考虑会主动使所有基于旧密码哈希的会话失效——这是默认行为,并非 Bug。其原理在于:Django 将用户密码哈希值嵌入 session 数据的认证签名中(通过 SESSION_AUTH_HASH 机制)。一旦 user.password 字段更新,request.user.get_session_auth_hash() 返回值随之改变,而现有 session 中存储的旧 auth hash 不再匹配,中间件(AuthenticationMiddleware)检测到不一致后,便将 request.user 重置为 AnonymousUser,即“会话被冲刷”。
你当前的视图存在两个关键问题:
- 未调用 update_session_auth_hash() → 导致会话立即失效;
-
直接赋值 user.password = make_password(...) 并 .save() → 绕过了 Django 用户模型的密码设置逻辑(如信号触发、密
码验证等),且未更新 session 认证哈希。
✅ 正确做法是使用 set_password() 方法(它会自动哈希并触发相关逻辑),并在保存后立即调用 update_session_auth_hash(request):
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')
# 验证旧密码(推荐使用 check_password)
if not check_password(psswd, request.user.password):
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() 必须在 user.save() 之后、响应返回之前调用;
- 不要手动操作 user.password 字段,始终优先使用 set_password();
- 若使用 CustomUser 模型,请确保其继承自 AbstractBaseUser 或 AbstractUser,并正确实现了 set_password;
- 此机制依赖 django.contrib.auth.middleware.AuthenticationMiddleware,请确认已启用。
总结:密码变更触发会话失效是 Django 的内置安全防护,而非异常。只需在修改密码后显式调用 update_session_auth_hash(request, user),即可无缝延续用户会话,兼顾安全性与用户体验。
# 解决方法
# 安全防护
# 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; ?>
】
相关推荐
- Win11如何添加/删除输入法 Win11切换中英
- Mac如何将HEIC图片格式转为JPG_Mac批量
- windows如何备份注册表_windows导出和
- 如何用正则与预处理结合精准拦截拼接式垃圾域名
- Win11怎么设置任务栏图标大小_Windows1
- 如何在Golang中配置代码格式化工具_使用gof
- Windows怎样拦截QQ浏览器广告_Window
- Win11怎么关闭专注助手 Win11关闭免打扰模
- 如何在Golang中捕获JSON序列化错误_Gol
- php做exe支持多线程吗_并发处理实现方式【详解
- Win10怎样卸载iTunes_Win10卸载iT
- Win11怎么设置屏保_Windows 11屏幕保
- php增删改查报错1054怎么办_字段名错误排查修
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- ACF 教程:如何正确更新嵌套在多层 Group
- mac怎么分屏_MAC双屏显示与分屏操作技巧【指南
- 如何在Golang中使用log包输出不同级别日志_
- Windows10怎么查看硬件信息_Windows
- Python网络超时处理_健壮性设计说明【指导】
- php嵌入式需要什么环境_搭建php+linux嵌
- 微信里的php文件怎么变mp4_微信接收php转m
- Windows10系统服务优化指南_Win10禁用
- c++中如何求一个数的平方根_c++ sqrt函数
- c++怎么使用std::tuple存储多元组数据_
- 网站内页做seo排名怎么做?
- c++23 std::expected怎么用 c+
- Win10怎样卸载TeamViewer_Win10
- c++中如何对数组进行排序_c++数组排序算法汇总
- Win11关机界面怎么改_Win11自定义关机画面
- Win11怎么查看已连接wifi密码 Win11查
- 一文详解网站被黑客入侵挂马解决办法
- Mac如何调整Dock栏大小和位置_Mac程序坞个
- c++怎么操作redis数据库_c++ hired
- Win11怎么关闭定位服务_保护Win11位置隐私
- 如何使用Golang捕获测试日志_Golang t
- 如何在Golang中处理模块包路径变化_Golan
- Windows10蓝屏SYSTEM_SERVICE
- Windows10电脑怎么查看硬盘通电时间_Win
- php修改数据怎么批量改状态_批量更新status
- Win11怎么关闭资讯和兴趣_Windows11任
- Win11怎样安装钉钉客户端_Win11安装钉钉教
- c++如何获取map中所有的键_C++遍历键值对提
- c# Task.ConfigureAwait(tr
- c++怎么使用std::unique实现去重_c+
- Mac如何修复应用程序权限问题_Mac磁盘工具修复
- Python多线程使用规范_线程安全解析【教程】
- Win11声音太小怎么办_Windows 11开启
- php增删改查需要哪些扩展_开启mysqli或pd
- 如何减少Golang内存碎片化_Golang内存分

码验证等),且未更新 session 认证哈希。
QQ客服