如何在 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; ?>
】
相关推荐
- Linux如何使用Curl发送请求_Linux下A
- Python文件和流处理指南_高效读写大体积数据文
- Python技术债务管理_长期维护解析【教程】
- Windows10系统更新错误0x80070002
- Windows 11登录时提示“用户配置文件服务登
- Windows任务计划服务异常原因_任务调度失败的
- 如何使用Golang recover捕获panic
- Windows的便笺功能如何使用?(桌面备忘技巧)
- 如何在Golang中优化文件读写性能_使用缓冲和并
- Bpmn 2.0的XML文件怎么画流程图
- Windows10如何更改鼠标灵敏度_Win10鼠
- php下载安装包太大怎么下载_分卷压缩下载方法【教
- Win11怎么设置右键刷新选项_Windows11
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- Win11怎么开启剪贴板历史记录_Windows1
- 如何在Golang中使用log包输出不同级别日志_
- 如何在Golang中实现并发消息队列消费者_Gol
- PHP怎么接收前端传的时间戳_处理时间戳参数转换技
- Win10怎么限制单程序CPU占用上限_Win10
- 如何使用Golang log设置日志输出格式_Go
- Windows系统被恶意软件破坏后的恢复策略_错误
- 如何使用Golang配置安全开发环境_防止敏感信息
- Win11怎么关闭小组件_Win11禁用任务栏天气
- Dapper的Execute方法的返回值是什么意思
- Win11怎么设置默认PDF阅读器 Win11修改
- 如何使用Golang理解结构体指针方法接收者_Go
- Mac如何使用听写功能_Mac语音输入打字【效率技
- 获取 PHP 文件最后修改时间的正确方法
- Python对象生命周期管理_创建销毁说明【指导】
- Windows11怎样开启游戏模式_Windows
- Windows11怎么用“记事本”自动换行与编码
- 如何高效获取循环末次生成的 NumPy 数组最后一
- XSLT怎么生成动态的HTML属性名和标签名
- Windows10系统怎么查看硬盘健康_Win10
- PHP怎么接收URL中的锚点参数_获取#后面参数值
- Win11声音太小怎么办_Windows 11开启
- VSC里PHP变量未定义报错怎么解决_错误抑制技巧
- Windows如何拦截2345弹窗广告_Windo
- c++ std::atomic如何保证原子性 c+
- php订单日志怎么按金额排序_php按订单金额排序
- Python列表推导式与字典推导式教程_简化代码高
- 如何使用正则表达式精确匹配最多含一个换行符的 st
- php修改数据怎么批量改状态_批量更新status
- 如何在 Go 中判断变量是否为函数类型
- Win11任务栏怎么调到左边_Win11开始菜单居
- Win10如何更改电脑休眠时间_Windows10
- 如何在Golang中处理模块包路径变化_Golan
- 如何在Golang中捕获HTTP服务器错误_Gol
- 如何有效拦截拼接式恶意域名的垃圾信息
- php下载安装后memory_limit怎么设置_

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