学城项目短信登录接口和短信验证码注册接口搭建

1. 短信登录接口

/1  创建此接口的序列化类

  1 由于短信登录的序列化类和多方式的登录的序列化类中获取token和全局钩子的代码一致

  所以我们把它们放一起封装为CommonLoginSerializer

# 全局钩子和获取token的模块封装
  class CommonLoginSerializer():

    def _get_token(self, user):
      payload = jwt_payload_handler(user)
      token = jwt_encode_handler(payload)
      return token

    def _get_user(self, attrs):
      raise APIException('请使用被重写的该方法')

    # 全局钩子
    # 写上 1.验证用户名密码的的逻辑 2.以及签发token的逻辑
    # 多方式登录,username可以是用户名,邮箱,电话
    # 之前用的是正则匹配 今天使用Q查询
    def validate(self,attrs):
      user = self._get_user(attrs)
      token = self._get_token(user) # 传入用户,根据用户来签发token
      # 把user和token放在序列化类的context
      # context是上下文
      self.context['username'] = user.username
      self.context['icon'] = str(user.icon)
      self.context['token'] = token
      return attrs

  2 写上短信验证码登录的序列化校验

  # 短信登录的序列化类
  from django.core.cache import cache # 会优先查找validate,类中找不到就去父类中找
  class LoginUserSMSSerializer(CommonLoginSerializer,serializers.Serializer):
    code = serializers.CharField(max_length=4)
    mobile = serializers.CharField()

    def _get_user(self,attrs): # attrs中有用户名和密码
      mobile = attrs.get('mobile')
      code = attrs.get('code')
      # 拿出发送过去的code和用户输入的code作对比
      old_code = cache.get('send_sms_code_%s'%mobile)
      if code == old_code:
        # 验证码正确,查出用户信息返回
        user = User.objects.filter(mobiel=mobile).first()
        if user:
          return user
        else:
          raise APIException('该手机号未在平台注册')
      else:
        raise APIException('验证码错误')

/2  创建视图类 

  将多方式登录和短信验证码登录相同的冗余代码封装起来

  def _common_login(self, request, *args, **kwargs):
    # 前端传入的格式:{mobile:123,code:3333}
    # 不可以和多方式登录使用同一个序列化类
    ser = self.get_serializer(data=request.data) # 进行序列化
    # 只要执行 is_valid 就会执行字段自己的校验,例如全局和局部钩子
    # 在这段程序中我们需要在序列化类中写自己的校验规则,生成token串
    ser.is_valid(raise_exception=True) # 进行校验,如果失败,则抛出异常
    username = ser.context.get('username')
    token = ser.context.get('token')
    icon = ser.context.get('icon')
    # 登录成功会显示出token和用户名
    return APIResponse(username=username, token=token, icon=icon)

  创建短信登录接口

  @action(methods=['POST'], detail=False)
  def send_login(self, request, *args, **kwargs):
  return self._common_login(request, *args, **kwargs)

2. 手机验证码注册接口 

/1  短信注册的序列化类

/2  视图类中接口的创建

/3  调试全局异常的报错模式

/4  知识点的补充

  主路由中为什么要写media

    因为django中默认是不允许前端直接访问项目的某个文件夹的(static文件夹中的除外)

    path('media/<path:path>',serve,{'document_root':settings.MEDIA_ROOT})

  配置文件中debug有什么作用

     debug让信息显示更丰富

     你访问的路由如果不存在,会把所有能访问到的路由都显示出来 

     程序出了异常,错误信息直接显示在浏览器上

     上线阶段,肯定要改成False

  allowed的作用

    只有debug 为Flase时,这个必须填

    限制后端项目(django项目 )能够部署在哪个ip的机器上

    写 *  表示所有地址都可以

posted @ 2023-07-03 22:26  ranbo145  阅读(60)  评论(0)    收藏  举报