如何在 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; ?>
】
相关推荐
- Win11怎么设置应用分屏_Windows11贴靠
- Win11怎么设置虚拟键盘_打开Win11屏幕键盘
- MAC如何快速搜索大文件_MAC磁盘空间分析与冗余
- c++ unordered_map怎么用 c++哈
- 如何使用Golang构建基础消息队列模拟_Gola
- Laravel 查询 JSON 列:高效筛选包含数
- PythonWeb前后端整合项目教程_FastAP
- php订单日志怎么记录发货_php记录订单发货操作
- mac怎么安装字体_MAC添加第三方字体与字体册管
- Windows10无法连接到Internet_Wi
- Windows10电脑怎么连接蓝牙设备_Win10
- Win11怎样安装微信开发者工具_Win11安装开
- Windows如何拦截2345弹窗广告_Windo
- Windows任务计划服务异常原因_任务调度失败的
- Win11如何更改任务栏颜色 Win11自定义任务
- Win11怎么设置闹钟_Windows 11时钟应
- c++ reinterpret_cast怎么用 c
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- php会话怎么开启_session_start函数
- 如何在Golang中实现文件下载_Golang文件
- Go 语言标准库为何不提供泛型切片的 Contai
- Win10怎么关闭自动更新错误弹窗_Win10策略
- Python文件操作优化_大文件与流处理解析【教程
- Mac怎么查看活动监视器_理解Mac进程和资源占用
- 如何在 Windows 11 中使用 AlomWa
- c++怎么调用nana库开发GUI_c++ 现代风
- Golang如何测试HTTP中间件_Golang
- LINUX怎么查看进程_LINUX ps命令查看运
- Win11怎么关闭OneDrive同步_Win11
- 跨文件调用类方法怎么用_php作用域操作符与自动加
- Windows怎样关闭开始菜单推荐广告_Windo
- Windows11怎么用“记事本”自动换行与编码
- Windows10如何更改日期格式_Win10区域
- Python对象比较与排序_集合使用说明【指导】
- Win11任务栏天气怎么关闭 Win11隐藏天气小
- Win11怎么更改鼠标指针_Windows 11自
- Win10怎样卸载自带Edge_Win10卸载Ed
- Linux如何安装JDK11_Linux环境变量配
- Windows 11登录时提示“用户配置文件服务登
- Windows10系统怎么查看防火墙状态_Win1
- Win11如何关闭游戏模式 Win11禁用Xbox
- VSC怎样在Linux运行PHP_Ubuntu系统
- 如何在 Python 测试中动态配置 @backo
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- Go 中 := 短变量声明的类型推导机制详解
- C++中的std::shared_from_thi
- php怎么下载安装后设置默认字符集_utf8配置步
- 手机php怎么转mp4_手机端php文件转mp4a
- Windows10怎么备份注册表_Windows1
- Windows蓝屏错误0x0000001E怎么修复

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