drf多方式登录接口(手机号邮箱验证码)登录
Posted XxMa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf多方式登录接口(手机号邮箱验证码)登录相关的知识,希望对你有一定的参考价值。
题目
##### 3 多方式登录接口####
-使用auth的user表扩写
-用户名+密码
-手机号+密码
-邮箱+密码
-签发token逻辑,放在序列化类中写
方式一:
serializer.py
from rest_framework import serializers
from .models import UserInfo
from rest_framework.exceptions import ValidationError
import re
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
class UserSerializer(serializers.ModelSerializer):
username = serializers.CharField() # 这个优先用这个,就不是映射过来的,就没有unique的限制了
class Meta:
model = UserInfo
# 大坑:继承ModelSerializer后,fields的字段是映射过来的
# username 是unique唯一的,反序列化校验的时候,字段自己的规则,会去数据库查询有没有这个用户,如果有,直接报错了
fields = [\'username\',\'password\'] # 只做反序列化的校验
# 这个东西的返回值必须是个字典,校验过后的数据
def validate(self,attrs): # attr是前端传入的,校验过后的数据,先校验字段自己的然后局部钩子最后全局钩子
# 1.获取前端传入的数据
username = attrs.get(\'username\')
password = attrs.get(\'password\')
# 2.查用户是否存在(先查出用户再校验密码,查用户有三种类型:手机号,邮箱,用户名)
if re.match(r\'^1[3-9][0-9]9$\', username):
user = UserInfo.objects.filter(phone=username).first()
elif re.match(r\'^.+@.+$\', username):
user = UserInfo.objects.filter(email=username).first()
else:
user = UserInfo.objects.filter(username=username).first()
if user and user.check_password(password): # 再校验密码
# 3.签发token
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.user = user
self.token = token
return attrs
else:
raise ValidationError(\'用户名或密码错误\')
views.py
from rest_framework.viewsets import ViewSet
from .serializer import UserSerializer
from rest_framework.response import Response
class UserView(ViewSet):
def login(self,request):
# 1 得到一个序列化类
ser = UserSerializer(data=request.data)
if ser.is_valid(): # 执行全局钩子
user = ser.user
token = ser.token
return Response(\'code\': 100, \'msg\': \'登录成功\', \'token\': token, \'username\': user.username)
else:
return Response(\'code\': 100, \'msg\': ser.errors)
urls.py
path(\'login/\',views.UserView.as_view(\'post\':\'login\'))
方式二:
serializer.py
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from rest_framework import serializers
from django.contrib.auth import authenticate
class UserSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, attrs):
credentials =
\'username\':attrs.get(\'username\'),
\'password\': attrs.get(\'password\')
if all(credentials.values()):
user = authenticate(**credentials)
if user:
if not user.is_active:
msg = \'滚蛋\'
raise serializers.ValidationError(msg)
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.token = token
return
\'token\':token,
\'user\': user
else:
msg = \'用户名密码错误\'
raise serializers.ValidationError(msg)
else:
msg = \'必须填写用户名和密码\'
raise serializers.ValidationError(msg)
backends.py
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from .models import UserInfo
class LoginBackend(ModelBackend):
# 校验规则可以自己写
def authenticate(self, request, username=None, password=None, **kwargs):
user = UserInfo.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))
if user is not None and user.check_password(password):
return user
settings.py
AUTHENTICATION_BACKENDS = [
\'app01.backends.LoginBackend\'
]
views.py
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from .serializer import UserSerializer
from .jwt_response import common_response
class UserView(ViewSet):
def login(self,request):
ser = UserSerializer(data=request.data)
if ser.is_valid():
username = ser.validated_data.get(\'user\')
token = ser.validated_data.get(\'token\')
response_data = common_response(token, username, request)
response = Response(response_data)
return response
return Response(ser.errors)
urls.py
urlpatterns = [
path(\'login/\',views.UserView.as_view(\'post\':\'login\')),
]
短信验证登录实现流程
短信验证登陆
1. 以电话号码为参数调用发送验证登录短信的后台接口
2. 后台接口生成4位或者6位的数字验证码
3. 将生成的验证码和手机号码以key-value方式放入缓存(比如redis),并设置好缓存有效时间
4. 调用发送模板短信方法(或者第三方短信运营商接口)发送短信
5. 点击触发登陆,以电话号码和验证码为参数,调用后台登录验证接口
6. 后台登录验证接口校验缓存中对应保留的信息
如果一致,返回登陆成功;
否则返回失败原因
注意点:
一定要设置好验证码有效时间
限制发送验证码的时间间隔和每日次数
以上是关于drf多方式登录接口(手机号邮箱验证码)登录的主要内容,如果未能解决你的问题,请参考以下文章