Django修改密码强制用户重新登录策略

django会话保持依赖两个中间件SessionMiddlewareAuthenticationMiddleware

SessionMiddleware:用于session的校验和下发(下发至request.session)

AuthenticationMiddleware:通过request.session获取用户对象,并比对此时用户认证和session中存储的认证是否相同.

 

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

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')
MIDDLEWARE = (
	# 获取cookie中sessionid对应的django_session并做校验,有效的时候会把session对象增加到request.session
	'django.contrib.sessions.middleware.SessionMiddleware', 
    # 根据request.session获取对应User并校验是否有效
	'django.contrib.auth.middleware.AuthenticationMiddleware',	
)

AuthenticationMiddleware源码:

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_hashuser.get_session_auth_hash()是否相同, django_sessionsession_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这么做就是要实现修改密码强制用户自动退出。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值