美文网首页
Django 2.1.7用户认证authenticate一直返回

Django 2.1.7用户认证authenticate一直返回

作者: 星星在线 | 来源:发表于2019-03-11 00:28 被阅读0次

Django本身的用户管理模块是很强大的,可以满足大多种情况,但是有时候我们要对接第三方登录认证系统,就需要自己实现登录认证,幸好Django为我们提供了重新登录认证的接口,可以很好的将第三方登录方式集成到Django认证系统中。

Django默认的认证方式在settings中的AUTHENTICATION_BACKENDS中定义,使用django.contrib.auth.backends.ModelBackend模块进行认证,如果我们要重新,自定义类继承此类即可,然后在settings.py文件中显示的声明AUTHENTICATION_BACKENDS就能修改我们的认证方式。

# 设置邮箱和用户名均可登录
AUTHENTICATION_BACKENDS = (
    'users.views.CustomBackend',

)

另外Django2.1本身提供的认证方式也有一点小问题,就是当我们的账号没有激活时,使用authenticate方法返回的一直是None,我们经常会使用下面的方式:

# 成功返回user对象,失败返回null
            user = authenticate(request, username=user_name, password=pass_word)

            # 如果不是null说明验证成功
            if user is not None:
                # 只有当用户激活时才给登录
                if user.is_active:

先认证用户名和密码,然后再判断用户是否激活。但是很抱歉,在Django2.1中,这种方式行不通,为什么呢?在默认的ModelBackend类中,有以下实现代码:

    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)
        try:
            user = UserModel._default_manager.get_by_natural_key(username)
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a nonexistent user (#20760).
            UserModel().set_password(password)
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

    def user_can_authenticate(self, user):
        """
        Reject users with is_active=False. Custom user models that don't have
        that attribute are allowed.
        """
        is_active = getattr(user, 'is_active', None)
        return is_active or is_active is None

看一下user_can_authenticate函数,判断is_active,如果没有认证那么返回False,这样authenticate函数就不会返回user对象,而是返回一个None,我们上面的那种认证方式就不能实现了。这个时候就需要重写我们的认证类。在重写认证类的时候要注意,一般我们都是重写authenticate方法,但是在Django2.1中,这个方法多了一个参数: request

class ModelBackend:
    """
    Authenticates against settings.AUTH_USER_MODEL.
    """

    def authenticate(self, request, username=None, password=None, **kwargs):
        ......
        ......

之前一直是没有写request参数,也没有传入,导致认证的时候一直报错,自定义认证没有生效,而且还导致所有认证方式都不能执行。跟踪了源码才发现这个问题,在这里记录一下,以后不要在犯了!!!!

相关文章

网友评论

      本文标题:Django 2.1.7用户认证authenticate一直返回

      本文链接:https://www.haomeiwen.com/subject/pxmmpqtx.html