多方式登录接口
视图类
新写法-------> res.is_valid (raise_exception=True)
from rest_framework.viewsets import ViewSet, GenericViewSet
from .serialize import CommentMulLoginSerializer
from luffy_api.utils.comment_response import MyResponse
from rest_framework.decorators import action
# 编写视图类
class MultimodeLoginView(GenericViewSet):
# 重写路由方法
@action(methods=['POST', 'GET'], detail=False, url_path='login', url_name='login')
def mul_login(self, request):
"""
1 老写法
username=request.data.get('username')
password=request.data.get('password')
查询用户,
UserInfo.objects.filter(username=username,password=password)
签发token
返回
"""
""" 新写法---> 仿 jwt 模块登录源码 """
# 对数据进行反序列化
res = CommentMulLoginSerializer(data=request.data)
# raise_exception=True 的含义是,一旦检出错误,自动return,不用我们手写return
res.is_valid(raise_exception=True)
username = res.context['username']
token = res.context['token']
icon = res.context['icon']
# 自己封装的 Response 方法
return MyResponse(username=username, token=token, icon=icon)
序列化类
★★★★★ 字段默认唯一性,需将字段修改
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.settings import api_settings
from rest_framework import serializers
from django.contrib import auth
import re
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from .models import UserInfo
uni
class CommentMulLoginSerializer(serializers.ModelSerializer):
username = serializers.CharField()
class Meta:
model = UserInfo
####### 因为此字段相当于映射为 username = serializers.CharField( unique=True )
####### password = serializers.CharField( unique=True )
####### 登陆的话,执行此校验规则时,会向数据库查找此字段, 发现数据库已经有了此字段, 会报错,因此需将 unique 改为 False || 重写字段
fields = ['username', 'password']
# 获取用户
def _get_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
if re.match(r'^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$', username):
# """authenticate只能是对 用户名-密码 两个字段进行验证, 别的字段就直接还回,不会验证。------> 源码分析的结果 """
# 所以这里不能用 authenticate 对 用户名-密码 以外的字段做验证
user = UserInfo.objects.filter(mobile=username).first()
elif re.match(r'^.+@.+$', username):
# """authenticate只能是对 用户名-密码 两个字段进行验证, 别的字段就直接还回,不会验证。------> 源码分析的结果 """
# 所以这里不能用 authenticate 对 用户名-密码 以外的字段做验证
user = UserInfo.objects.filter(email=username).first()
else:
user = auth.authenticate(username=username, password=password)
if user and user.check_password(password):
return user
else:
raise ValidationError('用户名或密码错误!') # 捕获异常
# 签发token
def _get_token(self, user):
try:
payload = jwt_payload_handler(user) # 根据当前登录用户荷载
token = jwt_encode_handler(payload) # 根据荷载生成token
return token
except Exception as e:
raise ValidationError(str(e))
def validate(self, attrs):
# 用户验证
user = self._get_user(attrs)
# 签发token
token = self._get_token(user)
self.context['token'] = token
self.context['username'] = user.username
self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
return attrs

浙公网安备 33010602011771号