[Django学习] 用户身份验证模块

django 用户身份验证模块(/django/contrib/auth/__init__.py)

在 settings.py 中,可以通过 AUTHENTICATION_BACKENDS 指定多个验证后台;
默认的一个后台是 django.contrib.auth.backends.ModelBackend
验证身份时,遇到第一个验证成功的就返回。

authenticate 方法
=============================================
对指定的用户名/密码或其他身份凭据(用 kwargs 方式指定的,因此可扩展)进行验证,
成功返回 user,失败返回 None.
如果验证成功,authenticate 方法还会给返回的 user 对象添加 backend 属性,指示是哪个配置的后台代码验证成功。

login 方法:
==============================================
向 session 中添加 user.id, user.backend 两个值。

logout 方法:
==============================================
去除上述两个值。

get_user 方法
==============================================
先取出 session 中的已登录的用户的 userid, backend 信息,
然后根据 backend 路径加载相关 backend 模块,
调用 backend 的 get_user 方法获取用户。
以上流程如果失败,则返回一个 AnonymousUser.

一般的用户登录代码:

from  django.contrib.auth  import  authenticate, login
username 
=  request.POST[ ' username ' ]
password 
=  request.POST[ ' password ' ]
user 
=  authenticate(username = username, password = password)
if  user  is   not  None:
    login(request, user)


那么 auth 这个包的 get_user 方法在什么地方用到呢,查了一下代码,发现在
/django/contrib/auth/middleware.py

class  LazyUser(object):
    
def   __get__ (self, request, obj_type = None):
        
if   not  hasattr(request,  ' _cached_user ' ):
            
from  django.contrib.auth  import  get_user
            request._cached_user 
=  get_user(request)
        
return  request._cached_user

class  AuthenticationMiddleware(object):
    
def  process_request(self, request):
        
assert  hasattr(request,  ' session ' ),  " The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'. "
        request.
__class__ .user  =  LazyUser()
        
return  None

这里给 request 注入了一个 user 属性,为了避免多次加载时反复调用 backend 的后台代码去数据库中读取用户,这里实现了一个 lazy-load 模式,用的是 __class__ 和 __get__ 结合的办法,很值得学习。我不清楚这个实现手段准确的叫法在 python 中是什么,大体是运行时通过修改类,去修改相关类实例的行为,这也是 python 动态性的优势的一个体现。

这样,我们在使用 request.user 的时候,就有内建的缓存机制了。

有时候,我们希望自动登录一个指定的用户,而这时候不知道用户的密码(密码可能是 hash 存储的)。但是默认的 authenticate 方法必须有 password 传递进去,其执行结果是给 user 对象赋了一个 backend 属性,为此我写了一个方法来模拟这个功能,实现不知道密码的情况下登录指定用户:
def  login_user(request, user):
    user.backend 
=   ' django.contrib.auth.backends.ModelBackend '
    
from  django.contrib.auth  import  login
    login(request, user)

这里所需的 user 参数我们可以直接通过某些其他的键值从数据库取得,比如 email 或者 id.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值