基于JWT认证的多方式登录

多方式登录

1 使用用户名,邮箱,手机号+密码都能登录成功
2 可以使用auth 的user表,也可以自定义用户表
3 扩写auth的user表,要么不用,要用一定要在项目开始就使用(没有迁移之前)
4 如果已经迁移了(正常是不能再使用了),如果还想用,解决方案:
-删库
-删除迁移记录(app的迁移记录,auth app的迁移记录(源码中),admin app的迁移记录(源码中))

1 视图层

from app01 import serializer, models, auth
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
class UserInfoView(ViewSet):
    @action(methods=['POST'], detail=False)
    def login(self, request):
        res = {'code': 100, 'msg': ''}
        user = serializer.UserSerializer(data=request.data)
        if user.is_valid():
            # 校验成功后生成token
            res['token'] = user.context['token']
            res['msg'] = '登录成功!'
        else:
            res['code'] = 101
            res['msg'] = user.errors
        return Response(res)

2 序列化类

from rest_framework import serializers
from app01 import models
import re
from rest_framework.exceptions import ValidationError
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()
    class Meta:
        model = models.User
        fields = ['username', 'password']
    def validate(self, attrs):
        # 将获取用户分离出一个函数
        user = self._get_user(attrs)
        # 将获取token分离出一个函数
        token = self._get_token(user)
        self.context['token'] = token
        return attrs

    def _get_user(self, attrs):
        # 先获取到用户名和密码
        username = attrs.get('username')
        password = attrs.get('password')
        # 根据用户名三种不同情况分别去对应字段查找
        if re.match(r'', username):
            user = models.User.objects.filter(phone=username).first()
        elif re.match(r'^.+@.+$', username):
            user = models.User.objects.filter(email=username).first()
        else:
            user = models.User.objects.filter(username=username).first()
        # 由于用的是auth扩展的用户表,密码是加密的
        if user:
            if user.check_password(password):
                return user
            else:
                raise ValidationError('用户名或密码错误')
        else:
            raise ValidationError('用户名或密码错误')

    def _get_token(self, user):
        # 使用jwt的方法获取token
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token
posted @ 2021-07-23 21:30  zheng-sn  阅读(421)  评论(0)    收藏  举报