美文网首页
自定义登录逻辑验证

自定义登录逻辑验证

作者: 入间 | 来源:发表于2018-07-07 16:56 被阅读0次

    django中的登录功能主要涉及到django.contrib.auth这个包,它提供了2个重要的函数:authenticate和login。

    django.contrib.auth.authenticate

    这个函数接受的一个收集参数,但至少需要接受username和password这两个关键参数,它完成以下的事情:

    从setting中获取AUTHENTICATION_BACKENDS的元组, 默认情况下是django.contrib.auth.backends.ModelBackend.
    遍历这整个元组,然后调用每一个Backend的authenticate方法,而每个Backend.authenticate会有一个登陆逻辑(自定义后面会提及),如ModelBackend.authenticate它拿传过来的账号密码的与数据库user model的username与password进行验证。
    如果Backend.authenticate验证通过,就会返回一个user对象,然后auth.authenticate将不再进行遍历,return user对象。如果返回None,就继续调用下一个Backend.authenticate。如果全部都返回None,那么验证不通过。

    django.contrib.auth.login

    login只会用在auth.authenticate返回一个user的情况下,这个函数会接着做下面的事情:

    生成一个新的session_id 放到request.session中(这个session在返回时会被session的中间件进行处理,将session_id放入到cookie当中)
    将这个user放到request.user中

    讲了那么多,我们来看一下代码:

    class LoginView(View):
        def get(self, request):
            pass
    
        def post(self, request):
            username = request.POST.get('username', '')
            password = request.POST.get('password', '')
            login_form = LoginForm(request.POST)
            if login_form.is_valid:
                user = auth.authenticate(username=username, password=password)
                if user is not None:
                    login(request, user)
                    # 如果登入成功,重定向要主页
                    return HttpResponseRedirect(reverse('index'))
                else:
                    # user为None,说明账号或密码错误
                    return render(request, "login.html", {"msg": "用户名或密码错误"})
            else:
                # 表单无效,返回login_form对象即可,在template调用login_form.errors这个字典去获取相关的错误
                return render(request, "login.html", {"login_form": login_form})
    

    显然,如果单纯使用ModelBackend.authenticate的验证逻辑是不能满足我们的需求,我们登录的账号可以是username,也可以是手机/邮箱等,这时候,我们可以进行一个自定义的登录逻辑验证。

    自定义的登录逻辑验证

    首先在view中写自己的Backend,最好直接继承ModelBackend
    重载authenticate方法,参数直接来自auth.authenticate,但因为验证需要用到表单中的username和password,所以前面提到,auth.authenticate也至少去接受这两个关键参数
    用Q方法可以在进行或操作,如果用','是使用与操作,由于数据库中的password是加密的,不能直接使用password=password,django为我们提供了check_password方法进行验证。
    如果验证通过需要返回user对象,否则返回None

    from django.db.models import Q
    from django.contrib.auth.hashers import make_password
    
    class MyUserBackend(ModelBackend):
        """
        自定义用户验证
        """
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                user = UserProfile.objects.get(Q(username=username) | Q(email=username) | Q(mobile=username))
                if user.check_password(password):
                    return user
            except Exception as e:
                return None
    

    然后在setting中配置

        # app+views+backend名字
        AUTHENTICATION_BACKENDS = (  
            'users.views.MyUserBackend',  
        )
    

    到这里基本上就配置完成了

    django.contrib.auth.logout

    顺便提及一下logout函数,由于django已经为我们提供好了退出的处理,使用起来十分简单:

    class LogoutView(View):
        def get(self, request):
            logout(request)
            return HttpResponseRedirect(reverse('index'))
    

    logout函数主要完成:
    将request.session清除
    request.user = AnonymousUser()将用户设置与匿名用户

    相关文章

      网友评论

          本文标题:自定义登录逻辑验证

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