django 自定义登陆验证逻辑

本文的django view采用的是基于cbv的模式html

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

django.contrib.auth.authenticate

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

  1. 从setting中获取AUTHENTICATION_BACKENDS的元组, 默认状况下是django.contrib.auth.backends.ModelBackend.
  2. 遍历这整个元组,而后调用每个Backend的authenticate方法,而每一个Backend.authenticate会有一个登录逻辑(自定义后面会说起),如ModelBackend.authenticate它拿传过来的帐号密码的与数据库user model的username与password进行验证。
  3. 若是Backend.authenticate验证经过,就会返回一个user对象,而后auth.authenticate将再也不进行遍历,return user对象。若是返回None,就继续调用下一个Backend.authenticate。若是所有都返回None,那么验证不经过。

django.contrib.auth.login

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

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

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

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,也能够是手机/邮箱等,这时候,咱们能够进行一个自定义的登陆逻辑验证。session

  1. 首先在view中写本身的Backend,最好直接继承ModelBackend
  2. 重载authenticate方法,参数直接来自auth.authenticate,但由于验证须要用到表单中的username和password,因此前面提到,auth.authenticate也至少去接受这两个关键参数
  3. 用Q方法能够在进行或操做,若是用','是使用与操做,因为数据库中的password是加密的,不能直接使用password=password,django为咱们提供了check_password方法进行验证。
  4. 若是验证经过须要返回user对象,不然返回None
  5. 在setting中配置
# app+views+backend名字
    AUTHENTICATION_BACKENDS = (  
        'users.views.MyUserBackend',  
    )
复制代码
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


复制代码

django.contrib.auth.logout

顺便说起一下logout函数,因为django已经为咱们提供好了退出的处理,使用起来十分简单:app

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

logout函数主要完成:函数

  1. 将request.session清除
  2. request.user = AnonymousUser()将用户设置与匿名用户
相关文章
相关标签/搜索