使用用户名/邮箱/手机号 + 密码登陆
- 多形式登陆其实很简单就是继承Django中ModelBackend并且重写authenticate()方法
源码分析:
class ModelBackend:
"""
Authenticates against settings.AUTH_USER_MODEL.
"""
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
通过查看源码我们可以看到Django默认的认证后端是判断用户的username和password这两个字段是否通过校验,但实际上,我们可能会有更多的登录需求,比如说,既可以通过用户名,也可以通过手机号或邮箱等登录,这时候我们可以重写authenticate()方法实现
1.我们新建一个py文件里面写一个类继承ModelBackend,并且重写authenticate()方法
第一种方法:这种方法通俗简单易懂
# 以前使用username进行用户验证,现在修改成email|phone进行验证 多形式登录
from user.models import User
class EmailAuthBackend:
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(username=username)
except Exception as e:
user = None
if not user:
try:
user = User.objects.get(email=username)
except Exception as e:
user = None
if not user:
try:
user = User.objects.get(phone=username)
except Exception as e:
user = None
if user and user.check_password(password):
return user
else:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
第二种方法:使用Q对象。( | )来获取username phone email
from django.contrib.auth.backends import ModelBackend
from user import models
from django.db.models import Q
class MultiformAuthBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))
if user is not None and user.check_password(password):
return user
except Exception as e:
print(e)
2.在setting.py配置文件
- 完成自定义的认证后端之后,我们还需要在配置文件里告诉Django要使用我们自定义的而不是默认的认证后端
# 自定义验证后端 多形式登录
# AUTHENTICATION_BACKENDS = [‘user.utils.EmailAuthBackend‘]
AUTHENTICATION_BACKENDS = [‘user.utils.MultiformAuthBackend‘]
其他类似链接参考:
【Django】创建用户,继承AbstractUser自定义用户模型类
【Django】自定义存储后端返回完整图片的URL链接