起因

BUG出现

系统升级django版本后经常出现自动退出登录

问题复现

系统升级django(大版本,如1.8、1.11和2.0)后,旧版与新版同时运行,同一各User用旧版authenticate验证后会导致新版中已登录User被退出。

正常使用中的登陆、退出和会话保持

登录

from django.contrib.auth import authenticate, login , logout

def login(request):

if request.method == "POST":

username = request.POST.get('username', '')

password = request.POST.get('password', '')

user = authenticate(username=username, password=password) # 验证用户帐号密码是否正确,通过后返回User对象

if not user:

login(request, user) # 登录,response添加cookie并将session_key记录到django_session

request.session.set_expiry(0)# 设置session失效时间,0表示关闭浏览器失效

return HttpResponseRedirect('/')

退出

from django.contrib.auth import authenticate, login , logout

def logout(request):

logout(request)# 清除response的cookie和django_session中记录

return HttpResponseRedirect('/login')

保持登陆状态

成功登录后浏览器将在每次请求时Header中附带cookie

settings.py配置:

SECRET_KEY = '%iai=j+uyd4s0t3qm$3w-w6^b0lf!df%hh-@5f!0&4enc(o7#5'# key变化密码的hash也会变

MIDDLEWARE = (

# ... 无关部分省略

'django.contrib.sessions.middleware.SessionMiddleware', # 获取cookie中sessionid对应的django_session,有效的时候会把session对象增加到request.session

'django.contrib.auth.middleware.AuthenticationMiddleware',# 根据request.session获取对应User并校验是否有效

# ... 无关部分省略

)

寻根溯源

具体过程比较曲折,一言难尽。

会话保持依赖两个中间件SessionMiddleware和AuthenticationMiddleware,其中AuthenticationMiddleware通过request.session获取用户对象,并比对此时用户认证和session中存储的认证是否相同

HASH_SESSION_KEY = '_auth_user_hash'

# auth.get_user

def get_user(request):

"""

Return the user model instance associated with the given request session.

If no user is retrieved, return an instance of `AnonymousUser`.

"""

from .models import AnonymousUser

user = None

try:

user_id = _get_user_session_key(request)

backend_path = request.session[BACKEND_SESSION_KEY]

except KeyError:

pass

else:

if backend_path in settings.AUTHENTICATION_BACKENDS:

backend = load_backend(backend_path)

user = backend.get_user(user_id)

# Verify the session

if hasattr(user, 'get_session_auth_hash'):

session_hash = request.session.get(HASH_SESSION_KEY)

session_hash_verified = session_hash and constant_time_compare(

session_hash,

user.get_session_auth_hash()

)

if not session_hash_verified:

request.session.flush()

user = None

return user or AnonymousUser()

也就是session_hash_verified = session_hash and constant_time_compare(session_hash,user.get_session_auth_hash()),对比session._auth_user_hash和user.get_session_auth_hash()是否相同 django_session中session_data默认存储的如下信息:

{

'_auth_user_id': '25',

'_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',

'_auth_user_hash': '54332f14831144a4022e7601c6dd3fcc531a5454',

'_session_expiry': 0

}

user.get_session_auth_hash()如下(User的父类):

class AbstractBaseUser(models.Model):

def get_session_auth_hash(self):

"""

Return an HMAC of the password field.

"""

key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"

return salted_hmac(key_salt, self.password).hexdigest()

那么影响hash的就是user.password,django这么做原本是要实现修改密码强制用户自动退出。django文档

修改密码强制用户自动退出的特性在django 2.0之前版本需要添加'django.contrib.auth.middleware.SessionAuthenticationMiddleware'到 MIDDLEWARE_CLASSES才能启用此特性,2.0开始移除此中间件并强制启用此特性

当用户密码被修改后,hash变化,判断为session失效

当不同版本django中authenticate()时会自动重新生成密码的密文,导致数据库中密码密文变化,hash也变化,判断为session失效,这就是文章开始bug的原因

升级django密码密文变化原因d

绕过修改密码强制退出的方法

两种方法

方法1: 每次请求不严重hash(仅适用于自定义User的) 屏蔽user.get_session_auth_hash()方法,使跳过hash比对

class User(AbstractBaseUser):

# ... 无关的省略

def __getattribute__(self, item):

if item == 'get_session_auth_hash':

raise AttributeError

return super().__getattribute__(item)

方法2: 保证不同版本密码密文一致 settings.py

PASSWORD_HASHERS = [

'core.password.CustomPBKDF2PasswordHasher',

]

core.password.py

from django.contrib.auth.hashers import PBKDF2PasswordHasher

class CustomPBKDF2PasswordHasher(PBKDF2PasswordHasher):

iterations = 20000# 所有系统指定此值为一样,能使密码密文不变

session 修改密码python_django修改密码强制退出机制相关推荐

  1. 强制修改LINUX的root密码

    如何强制修改LINUX的root密码 前言 一.按电源键启动服务器 二.按e键进入命令行模式 1.在linux开头末尾加入几行命令ctrl+x保存退出 2.在该界面进行root密码破解 前言 由于管理 ...

  2. jwt用户注销 PHP,关于JWT用户主动注销、强制登出、忘记密码、修改密码的一些思考...

    JWT(JSON WEB TOKEN)的特点是无状态,通常用来作为验证登录以及鉴权,在这一方面,JWT体现出了他的优点. 然而,如果使用JWT实现,用户主动注销.强制登出(禁止登陆).忘记密码.修改密 ...

  3. SpringBoot-项目1-用户(注册,登录,修改密码,修改个人资料,上传头像)

    1. 项目分析 在设计一款软件时,在编写代码之前,应该先分析这个项目中需要处理哪些类型的数据!例如,本项目中需要处理的数据种类有:收藏,购物车,用户,收货地址,订单,商品,商品类别. 当确定了需要处理 ...

  4. 嵌入式arm linux 文件系统登入密码的修改笔记

    1.设置登录时需要用户和用户密码,在/etc/inittab文件中添加: ::respawn:/sbin/getty -L ttyPS0 115200 vt100  或  ::respawn:-/bi ...

  5. linux的mysql修改用户密码与忘记密码的方法

    目录 1.第一种创建用户并授权(也可用于改密码) 2.直接alter改 3.用UPDATE直接编辑user表 4.忘记数据库root密码 1.第一种创建用户并授权(也可用于改密码) 第一步:先查看基本 ...

  6. 域控下更改服务器密码策略,修改windows-2008-域控服务器密码策略

    <修改windows-2008-域控服务器密码策略>由会员分享,可在线阅读,更多相关<修改windows-2008-域控服务器密码策略(2页珍藏版)>请在人人文库网上搜索. 1 ...

  7. 腾讯云服务器修改和重置登录密码图文教程

    在上一篇我们介绍了如何购买腾讯云服务器,现在来讲讲购买服务器之后,如何重置和修改腾讯云服务器密码.步骤过程很简单,虽然我描述的有点详细. [修改云服务器密码(Linux操作系统)] 远程连接 Linu ...

  8. access control延迟锁门_RFID ACCESS CONTROL门禁感应器的密码的修改方法

    RFID ACCESS CONTROL 门禁感应器的密码的修改方法: 方法一: 1 .初始密码:编程密码为 9999 ,使用密码为 1234 . 2 .进入编程状态:功能设置(需在编程状态下)门状态监 ...

  9. 安心邮服务器修改密码步骤,邮件系统密码修改操作说明

    原标题:邮件系统密码修改操作说明 第一步:在电脑上登录邮件系统,输入网址https://mail.bjut.edu.cn,出现登录页面如下图所示. 第二步:输入自己邮箱的用户名和密码,点击登录. 1. ...

  10. Linux如何修改root用户的密码

    Linux系统的root账号是非常重要的一个账号,也是权限最大的一个账号,但是有时候忘了root密码怎么办?总不能重装系统吧,这个是下下策,其实Linux系统中,如果忘记了root账号密码,是可以通过 ...

最新文章

  1. CentOS6.3编译安装Nginx1.4.7 + MySQL5.5.25a + PHP5.3.28
  2. js两个等号和三个等号_js中两个等号(==)和三个等号(===)的区别
  3. yum之如何手动创建本地yum仓库
  4. 小小攻城师,步步达成梦想!
  5. [python opencv 计算机视觉零基础到实战] 十五 直方图反向投影
  6. 容器编排技术 -- Pod 安全策略
  7. 手机可用熵_时间之矢,生命之熵
  8. 【转】在Ubuntu上下载、编译和安装Android最新源代码
  9. 高中计算机学ppt吗,高中信息技术人工智能教学培训课件选修5ppt
  10. JavaScript运动应用一
  11. sklearn学习之LR算法实践
  12. 在计算机里面建一个新的文档,电脑上的word怎么新建文档
  13. 网上邻居找不到服务器怎么办,Win7网上邻居消失了怎么办?Win7网上邻居不能使用的原因及解决方法...
  14. 百度网盘客户端刷不出内容,网页版打不开,怎么办?
  15. 隐藏桌面图标通过命令行启动
  16. android 京东平板布局,京东商城上线安卓Pad客户端 完美布局移动端
  17. Python轻松制作王者荣耀自动刷金币脚本
  18. 磁共振钆造影剂 Au/Fe3O4复合CT/MRI双模态造影剂 四氧化三铁纳米粒子的磁共振成像造影剂
  19. ream完美转换XML、JSON 转载
  20. ZOJ 3755 - Mines (状压DP)

热门文章

  1. bug_ warning: control reaches end of non-void function
  2. warning: control reaches end of non-void function(C语言编译报错)
  3. GRYZ 模 拟 赛 系 列 Xxy 的车厢调度
  4. 数据结构教程(第5版)李春葆 课后习题及答案(PDF版)
  5. 怎样去提高效率,五步优化法
  6. RuntimeError: NCCL error in:XXX,unhandled system error, NCCL version 2.7.8
  7. python猜数字统计游戏次数_详解用Python语言写的一个猜数字游戏
  8. virtualbox硬件加速_虚拟机安装后必做的3项设置,解决运行卡慢问题,提速十倍!...
  9. 采样频率和带宽的关系_示波器的带宽与采样率是什么关系
  10. 云计算的特点,主要有哪些?