注册接口异常是什么意思啊(登录注册接口搭建)
导读:登录接口分析 登录分为多方式登录和验证码登录方式 多方式登录 1)前台提供账号密码,账号可能是 用户名、手机号、邮箱等 接口: 后台只需要提供一个多方式登录接口即可 - 多方式登录接口...
登录接口分析
登录分为多方式登录和验证码登录方式
多方式登录 1)前台提供账号密码 ,账号可能是 用户名 、手机号 、邮箱等 接口: 后台只需要提供一个多方式登录接口即可 - 多方式登录接口多方式登录接口
前端输入完账号和密码 ,点击登录 ,向后端发送请求进行校验用户登录数据
urls.py
from django.urls import path,re_path,include from rest_framework.routers import SimpleRouter from user import views router = SimpleRouter() router.register(,views.LoginView,login) urlpatterns = [ path(,include(router.urls)), ]views.py
from rest_framework.viewsets import ViewSet from user import serializers from luffyapi.utils.response import APIResponse from rest_framework.decorators import action class LoginView(ViewSet): # 密码方式登录接口 @action(methods=[POST],detail=False) # 加入action装饰器 ,自动生成路由 def login(self,request,*args,**kwargs): # 把前端传入的用户登录数据传入序列化器 ser = serializers.UserModelserialize(data=request.data) # 判读传入的数据是否合法 if ser.is_valid(): # 合法获取token和用户名 token =ser.context[token] username = ser.context[user].username # 然后返回给前端 return APIResponse(token=token,username=username) else: return APIResponse(code=0,msg=ser.errors)serializes.py
from rest_framework import serializers from user import models from rest_framework.exceptions import ValidationError class UserModelserialize(serializers.ModelSerializer): username = serializers.CharField() # ? class Meta: model = models.UserInfo fields = [username,password,id] extra_kwargs = { id:{read_only:True}, password: {write_only: True}, } def validate(self, attrs): # 多种方式登录 user = self._get_user(attrs) # 签发token token = self._get_token(user) # 放到context中 ,我在视图函数中可以取出来 self.context[token] = token self.context[user] = user return attrs # 校验前端发来的数据 def _get_user(self, attrs): # 获取前端发送的数据 username = attrs.get(username) password = attrs.get(password) import re # 校验前端的用户是否为手机号 、邮箱 、用户名登录 if re.match(^1[3-9][0-9]{9}$,username): user = models.UserInfo.objects.filter(telephone=username).first() elif re.match(^.+@.+$,username): user = models.UserInfo.objects.filter(email=username).first() else: user = models.UserInfo.objects.filter(username=username).first() # 用户名存在 ,则校验密码 if user: ret = user.check_password(password) if ret: return user else: raise ValidationError(密码错误) else: raise ValidationError(用户名不存在) # 签发token函数 ,前面加一个_暗示内部使用的 def _get_token(self,user): from rest_framework_jwt.serializers import jwt_payload_handler,jwt_encode_handler pyload = jwt_payload_handler(user) #通过user对象获取pyload token = jwt_encode_handler(pyload) #通过pyload获取token return token 验证码登录验证码可以保存在redis里 ,也可以保存在缓存里
1)前台提供手机号和验证码完成登录 接口: 前台填完手机号 ,往后台发送校验手机号的请求 ,如果存在继续 ,不存在提示注册 - 手机号存在与否接口 前台点击发送验证码 ,将手机再次发送给后台,后台将手机号通知给第三方 ,发送短信 - 手机验证码接口 前台点击登录提交手机号与验证码 ,完成验证码登录 - 验证码登录接口手机号是否存在的接口设计
# 校验手机号是否存在接口 @action(methods=[GET], detail=False) def check_telephone(self, request, *args, **kwargs): telephone = request.GET.get(telephone) if not re.match(^1[3-9][0-9]{9}$,telephone): return APIResponse(code=0,msg=手机号不合法) try: models.UserInfo.objects.get(telephone=telephone) return APIResponse() except: return APIResponse(code=0,msg=手机号不存在)发送验证码接口
from luffyapi.libs.tx_msg import get_code,send_message # 导入封装好的短信接口 from django.core.cache import cache # 导入缓存 from django.conf import settings # 发送验证码接口 @action(methods=[GET], detail=False) def send(self,request,*args,**kwargs): telephone = request.GET.get(telephone) if not re.match(^1[3-9][0-9]{9}$,telephone): return APIResponse(code=0,msg=手机号不合法) code = get_code() #获取随机验证码 result = send_message(telephone,code) # 将验证码保存到缓存中备用,参数分别是key ,value ,过期时间秒 # 这个telephone可以有标识一点 ,在settings进行配置一下 cache.set(settings.CACHE_MSG % telephone,code,180) # 如果result返回true if result: return APIResponse(msg=验证码发送成功) else: return APIResponse(code=0,msg=验证码发送失败)短信发送频率限制
写一个throttlings.py
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle # 写一个类继承SimpleRateThrottle class TimeThrottling(SimpleRateThrottle): scope = sms def get_cache_key(self, request, view): telephone = request.query_params.get(telephone) return self.cache_format%{scope:sms,ident:telephone} # 以手机号返回不太好 ,换一种不易重名的返回做限制在settings里配置一下频率
REST_FRAMEWORK = { DEFAULT_THROTTLE_RATES: { sms: 1/m # 一分钟访问1次 } }views.py
from . import throttlings class SendView(ViewSet): # 发送短信频率限制 throttle_classes = [throttlings.TimeThrottling] # 发送验证码接口 @action(methods=[GET], detail=False) def send(self,request,*args,**kwargs): telephone = request.query_params.get(telephone) if not re.match(^1[3-9][0-9]{9}$,telephone): return APIResponse(code=0,msg=手机号不合法) code = get_code() #获取随机验证码 result = send_message(telephone,code) # 将验证码保存到缓存中备用 ,参数分别是key ,value ,过期时间秒 # 这个telephone可以有标识一点 ,在settings进行配置一下 cache.set(settings.CACHE_MSG % telephone,code,180) # 如果result返回true if result: return APIResponse(msg=验证码发送成功) else: return APIResponse(code=0,msg=验证码发送失败)手机号登陆接口
serializes.py
作用:对前端发来的手机号和验证码进行校验 ,并签发token class UserCodeModelserialize(serializers.ModelSerializer): code = serializers.CharField(max_length=4,min_length=4) class Meta: model = models.UserInfo fields = [telephone,code] # 这里因为手机号验证码方式登录也需要校验和签发token ,所以也需要重写validate方法 def validate(self, attrs): user = self._get_user(attrs) token = self._get_token(user) self.context[user] = user self.context[token] = token return attrs def _get_user(self, attrs): # 获取前端发送的数据 telephone = attrs.get(telephone) code = attrs.get(code) # 取出生产的code与用户传的code做比较 cache_code = cache.get(settings.CACHE_MSG%telephone) if cache_code == code: user = models.UserInfo.objects.filter(telephone=telephone).first() if user: cache.set(settings.CACHE_MSG%telephone,) return user else: raise ValidationError(用户不存在) else: raise ValidationError(验证码不正确) # 签发token函数 ,前面加一个_暗示内部使用的 def _get_token(self,user): from rest_framework_jwt.serializers import jwt_payload_handler,jwt_encode_handler pyload = jwt_payload_handler(user) #通过user对象获取pyload token = jwt_encode_handler(pyload) #通过pyload获取token return tokenviews.py
# 验证码方式登录接口 @action(methods=[POST], detail=False) def code_login(self, request, *args, **kwargs): # 把前端传入的用户登录数据传入序列化器 ser = serializers.UserCodeModelserialize(data=request.data) # 判读传入的数据是否合法 if ser.is_valid(): # 合法获取token和用户名 token = ser.context[token] username = ser.context[user].username # 然后返回给前端 return APIResponse(token=token, username=username) else: return APIResponse(code=0, msg=ser.errors)创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!