首页 > 其他分享 >路飞项目 - 登录注册

路飞项目 - 登录注册

时间:2023-03-03 19:00:09浏览次数:49  
标签:username 登录 get 校验 路飞 token user 注册 序列化

目录

1 登录注册功能分析

① 多方式登录接口:用户名、手机号、邮箱 + 密码都可以登录

② 发送手机验证码接口 (借助于第三方短信平台)

③ 短信登录接口

④ 注册接口

⑤ 校验手机号是否存在的接口

2 手机号是否存在接口

判断手机号是否存在接口,也就是发送get请求的时候。

通过在 地址的?后面携带的手机号判断手机号是否存在的接口

2.1 urls.py

分发应用user的路由

from rest_framework.routers import SimpleRouter
from . import views

router = SimpleRouter()

router.register('usermsg', views.UserView, 'usermsg')

urlpatterns = [

]
urlpatterns += router.urls

2.2 views.py

视图函数在UserView类中处理

class UserView(GenericViewSet):
      @action(methods=['GET'],detail=False)
    def send_sms(self, request, *args, **kwargs):
        # 从地址栏中获取手机号来发送短信
        try:
            mobile = request.query_params.get('mobile')
            # get
            User.objects.get(mobile)
        except Exception as e:
            # raise e
            raise APIException('手机号不存在')
        return MyResponse(msg='手机号已经存在')

学会通过异常判断来处理,由于我们已经封装了全局异常处理,所以我们直接抛异常,前端也可以拿到定制返回的信息字典,包括 code和msg

3 多方式登录接口

无论使用用户名、邮箱、手机号当做用户名,配合密码都可以登录账号,返回token

3.1 views.py

在视图类中,我们将校验的逻辑放到序列化类中,而视图类中只获取在序列化类中校验后的数据,包括登录成功后返回的username和token,

# 用户功能
class UserView(GenericViewSet):
    serializer_class = UserLoginSerializer
    queryset = User.objects.all().filter(is_active=True)  # 校验auth_user表中的活跃用户才可以登录
    
    
    # 使用action装饰器来保证接口的安全
    @action(methods=['POST'], detail=False)
    def login_multiple(self, request, *args, **kwargs):
        # 获得序列化对象
        # ser = UserLoginSerializer()
        ser = self.get_serializer(data=request.data)
        # 执行序列化类自己的字段校验、局部钩子、全局钩子
        ser.is_valid(raise_exception=True)
        token = ser.context.get('token')
        username = ser.context.get('username')
        # return Response({'code': 100, 'msg': '成功', 'token': 'asfa', 'username': 'xxx'})
        # 使用自己封装的Response 这样code和msg会使用默认的
        return MyResponse(token=token, username=username)

raise_exception设置为False时,如果在反序列化过程中遇到错误,序列化器会将错误信息添加到serializer.errors属性中,并返回一个空的字典或者列表(具体取决于序列化器的类型)。这种方式适用于前端需要对错误信息进行处理的情况。

raise_exception设置为True时,如果在反序列化过程中遇到错误,序列化器会抛出rest_framework.exceptions.ValidationError异常,该异常包含错误信息。这种方式适用于后端需要对错误进行处理的情况。

3.2 serializers.py

在序列化器中,我们通过在视图类中调用is_valid()方法,来校验前端传入的数据,但是并不使用序列化器的序列化和反序列化功能柜,

import re

from rest_framework import serializers
from .models import User
from rest_framework.exceptions import APIException
import rest_framework_jwt.utils
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 UserLoginSerializer(serializers.ModelSerializer):
	
    username = serializers.CharField()

    class Meta:
        model = User
        fields = ['username', 'password']

    # 全局钩子
    def validate(self, attrs):  # attrs是前端传入的数据,经过字段自己校验和局部钩子校验过后的数据

        """
        1 我们要取出前端传入的用户名和密码
        2 要判断前端传入的用户名是 手机号、用户名、还是邮箱,结合密码区数据库中查询
        3 比对数据库中的数据,签发token
        4 比对后的结果返回给前端
        """
        # 自己编写类方法来获取user和token
        user = self._get_user(attrs)
        token = self._get_token(user)

        # 获取user和token后要通过序列化类的对象中的 context传给视图类
        self.context['username'] = user.username
        self.context['token'] = token

        return attrs

    def _get_user(self, attrs):
        """获取user的逻辑,在这里编写,增加拓展性"""
        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):
            user = User.objects.filter(mobile=username).first()
        elif re.match(r'^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$', username):
            user = User.objects.filter(email=username).first()
        else:
            user = User.objects.filter(username=username).first()

        # 校验用户和密码,如果有一个错了则抛出异常
        if user and user.check_password(password):
            return user
        else:
            raise APIException('用户名或者密码不存在')

    def _get_token(self, user):
        """通过user获取token,通过drf的jwt认证来获取"""
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        return token

由于使用了ModelSerializer,所以我们在映射的时候,会将AUTH模块的abtractuser表,所以由于username字段默认有unique=True的限制,所以在使用序列化器做序列化的时候会校验不通过,所以我们需要重写username字段的校验

image-20230303184952779

image-20230303165726225

标签:username,登录,get,校验,路飞,token,user,注册,序列化
From: https://www.cnblogs.com/DuoDuosg/p/17176674.html

相关文章

  • python之路81 路飞项目、为开源代码贡献代码、pycharm使用git、登录注册功能分析、手
    为开源项目贡献代码#github,gitee看到好的开源项目,发现有bug,为他增加新功能---》你加入了代码---》想合并进开源项目,如何做#步骤:1先fork开源项目--》复制这......
  • 路飞-登录注册功能
    1.注册功能因为路飞项目有很多不同的板块,所以我们分为两个app,一个home用来写主页的功能,一个user用来写用户相关功能。用户注册逻辑我们首先来写手机号是否已注册的接口:us......
  • 路飞项目---day07()
    昨日回顾#GIt内容大回顾#1版本管理软件:git,svn -代码合并-代码版本管理-协同开发,合并代码#2git跟svn区别#3git安装:相应平台软件,下载完成,一路下......
  • 【前端开发】一个滑动滑块校验登录的组件思路(用vue写的)
    <template><el-dialog:visible.sync="dialogVisible"custom-class="slideVerifyDialog":close-on-click-modal="false"title="身份验证"widt......
  • 为开源项目贡献代码、pycharm使用git、登录注册功能分析、手机号是否存在接口、多方式
    目录1为开源项目贡献代码2pycharm使用git2.1先配置pycharm使用git3登录注册功能分析4手机号是否存在接口4.2视图函数模版5多方式登录接口5.1视图类5.2序列化类6......
  • 统一单点登录&跳转
    在客户端输入地址(xxx.xxx.xxx/controll/方法/参数)服务端到controll层进行数据匹配 跳转前端响应情况图片跳转与列表跳转图片:编写跳转函数列表公用图片跳转函数,@c......
  • springcloud之nacos(二)Dubbo 融合 Nacos 成为注册中心
    一、项目依赖首先在父pom中定义以下依赖管理器信息:(使用2.1版本nacos,提前安装)<properties><java.version>1.8</java.version><project.build.sourceEncoding......
  • 路飞项目day05
    昨日内容回顾#1前端首页#2轮播图接口Banner.vue---->created--->axios--->渲染在页面上v-if#3git介绍-软件,版本管理软件-代码版本管......
  • 路飞1
    后台日志封装日志的作用就是用来记录一些错误信息和操作的,所以我们在以后的项目中都尽量不要出现print了,以后都使用日志logger.info(),以后只需要调整日志级别就好了日......
  • 路飞首页前端
    路飞前台的全局CSS,全局配置文件整理项目App.vue<template><divid="app"><router-view/></div></template>router/index.jsconstroutes=[{pa......