多方式认证原理
我们平常使用的Django登录认证是django.contrib.auth.authenticate
点进去源码,我们会看到这个函数,真正的认证类是它里面的那个
继续点进去源码,会看到ModelBacked
类,内部是用户名登录认证校验,它上一层就是基类了,所以我们只要重写这个类的authenticate
函数即可。
实现
第一步,写一个函数,继承ModelBackend
类,authenticate.py
:
import re
from django.contrib.auth.backends import ModelBackend
from users.models import UserInfo
class ReModelBackend(ModelBackend):
"""登录多方式认证类(支持手机号和用户名登录)"""
def authenticate(self, request, username=None, password=None, **kwargs):
"""重写authenticate方法"""
user = self.user_or_none(username)
if user and user.check_password(password):
return user
else:
return None
def user_or_none(self, account):
"""
自定义方法
account: 用户名或手机号
return: user对象或None
"""
is_match = re.match(r"1[3-9]\d{9}$", account)
try:
if is_match:
user = UserInfo.objects.get(mobile=account)
else:
user = UserInfo.objects.get(username=account)
except:
return None
else:
return user
第二步,Django配置,settings.py
# 列表内是导包路径
AUTHENTICATION_BACKENDS = ['extension.authenticate.ReModelBackend']
Django全局配置中也可以看到配置项
第三步,调用,登录视图示例,users/views.py
from django.shortcuts import render, HttpResponse, redirect, reverse
from django.views import View
from django.contrib.auth import login, authenticate
from .forms import LoginForm
from .models import UserInfo
class LoginView(View):
"""登录视图"""
def get(self, request):
return render(request, "login.html")
def post(self, request):
form_obj = LoginForm(request.POST)
if not form_obj.is_valid():
return render(request, "login.html", {"return_msg": "数据校验失败."})
username = form_obj.cleaned_data.get("username")
password = form_obj.cleaned_data.get("password")
remembered = form_obj.cleaned_data.get("remembered")
# 多方式认证登录
user = authenticate(username=username, password=password)
if not user:
return render(request, "login.html", {"return_msg": "用户名或密码错误."})
login(request, user)
# 设置失效时间
if not remembered:
request.session.set_expiry(0)
else:
request.session.set_expiry(None)
return redirect(reverse("contents:index"))
登录表单认证,users/forms.py
from django import forms
from .models import UserInfo
class LoginForm(forms.Form):
username = forms.CharField(max_length=20, min_length=5, required=True, label="用户名", error_messages={
"max_length": "用户名最大长度为20",
"min_length": "用户名最小长度为5",
"required": "用户名不能为空"
})
password = forms.CharField(max_length=20, min_length=8, required=True, label="密码", error_messages={
"max_length": "密码最大长度为20",
"min_length": "密码最小长度为8",
"required": "密码不能为空"
})
remembered = forms.BooleanField(required=False)
标签:password,return,登录,request,认证,authenticate,user,import,Django
From: https://www.cnblogs.com/hkwJsxl/p/17607863.html