多方式登录

1. 前后端项目上传到gitee

我们看到的好多开源项目,前后端都在一个仓库中 ----》是为了方便

正常我们开发代码,一个项目一个仓库

1.  后端仓库创建好了,提交过了 ---》继续提交 

  - git add .

  - git commit -m '注释'

  - git push origin master 

2. 前端

  创建远程仓库

  本地按上面命令,提交上去即可(配置远程remote地址)

2. 后端多方式登录接口

分析:

 -1. 前端携带的数据:{username:用户名/手机号/邮箱,password:密码(可以使用md5加密)}

 -2. 注册的时候:密码也是md5加密后带过来的

 -3. 我们登录的时候,带的密码(如果是md5加密的)---》后端校验通不过

后端:

 - request.data中取出前端携带的数据

 - 校验用户名密码是否正确 ---》校验逻辑写到序列化类中(序列化中username字段要重写,因为unique的特点)

 - 配合序列化类 ---》 全局钩子中写逻辑,签发token

 - 返回给前端

总结:

1. 序列化类实例化得到对象时要 :ser=UserLoginSerializer(data=request.data)    data=request.data  不能传给第一个位置(instance )

2. 被 APIResponse 序列化的数据类型 必须是 数字,字符串,列表,字典,不能是其他对象类型

3. 配置文件中写了个 后台项目地址

apps 中的user app:

序列化类:

新建一个serializer文件

from rest_framework import serializers
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
import re
from rest_framework.exceptions import ValidationError
from .models import User
from django.conf import settings


class UserLoginSerializer(serializers.Serializer):
    # 要重写字段,因为字段自己的规则通不过,因为unique
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        # 1. 校验用户
        user = self._get_user(attrs)  # attrs:是前端传入校验过后的数据对象
        # 2.签发token
        token = self._get_token(user)
        # 将签发的token和username放到context中
        self.context['username'] = user.username
        self.context['token'] = token
        self.context['icon'] = settings.BACKEND_URL+'/media'+str(user.icon)    #user.icon 是对象形式,序列化类只能序列化字符串
        # 返回attrs
        return attrs

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        # 进行正则匹配
        if re.match(r'^1[3-9][0-9]{9}', username):
            # 手机号登录
            user = User.objects.filter(mobile=username).first()
        elif re.match(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', username):
            # 邮箱登录  
            user = User.objects.filter(email=username).first()
        else:
            # 用户名登录
            user = User.objects.filter(username=username).first()
        # 因为数据库中的password是密文,前端提交的密码是明文,所以使用check_password
        if user and user.check_password(password):
            return user
        else:
            raise ValidationError('用户名或密码错误')
    #签发token
    def _get_token(self, user):
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token

视图类:

from django.shortcuts import render

# Create your views here.
from django.utils.datastructures import MultiValueDictKeyError
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from utils.common_response import APIResponse
from rest_framework.viewsets import GenericViewSet
from .models import User
from .serializer import UserLoginSerializer


# 验证手机号是否存在接口
class MobileView(ViewSet):
    @action(methods=['GET'], detail=False)
    def check_mobile(self, request, *args, **kwargs):
        try:
            # 取出前端传入的手机哈
            mobile = request.query_params['mobile']
            User.objects.get(mobile=mobile)  # 有且只有一个才不报错,否则报错
        except MultiValueDictKeyError as e:
            raise Exception('您没有携带手机号')
        except Exception as e:
            raise Exception('未知错误,请联系管理员')
        return APIResponse(msg='手机号已存在')


# 多方式登录接口
class UserLoginView(GenericViewSet):
    serializer_class = UserLoginSerializer

    @action(methods=['POST'], detail=False)
    def mul_login(self, request, *args, **kwargs):
        ser = self.get_serializer(data=request.data)
        ser.is_valid(raise_exception=True)
        username = ser.context.get('username')
        token = ser.context.get('token')
        icon = ser.context.get('icon')  # icon 必须是字符串形式,不能是对象形式
        return APIResponse(username=username,token=token,icon=icon)

如图:

 

路由:

user app下的urls:

from rest_framework.routers import SimpleRouter
from .views import MobileView,UserLoginView

router = SimpleRouter()
router.register('mobile', MobileView, 'mobile')
router.register('login',UserLoginView,'login')
urlpatterns = [

]
urlpatterns += router.urls

如图:

 简单测试:

 

posted @ 2023-10-13 16:18  Maverick-Lucky  阅读(38)  评论(0)    收藏  举报