zoukankan      html  css  js  c++  java
  • [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.

  • 相关阅读:
    美国商务签证面试经历
    正则表达式匹配字符串中的数值部分并将其返回
    在WPF中使用水晶报表for vs2010的方法
    Wpf中用代码执行控件的单击事件
    WPF项目中使用水晶报表for vs2010时的一个找不到程序集的问题
    WinForm实现全屏方法
    wpf中将数据导出为Excel
    WinForm实现窗体上控件的自由拖动
    在WPF中使用WinForm控件方法
    多样、互动的WinForm UI设计与开发思路(Flash、Html等)
  • 原文地址:https://www.cnblogs.com/RChen/p/django_auth.html
Copyright © 2011-2022 走看看