目录
路飞之登录注册接口
登录接口
接口分析可知,登录注册接口需要五个接口,分别是校验手机号是否存在的接口、多方式登录接口(用户名/手机号/邮箱+密码),发送手机验证码接口(借助于第三方短信平台)、短信登录接口、注册接口
-
总路由分发user路由
# 总路由 path('api/v1/user/',include('user.urls')) # 路由 from rest_framework.routers import SimpleRouter from .views import UserView router = SimpleRouter() # 访问 http://127.0.0.1:8000/api/v1/user/userinfo/send_msg ---->get 发送短信 router.register('userinfo',UserView , 'userinfo') urlpatterns = [ ] urlpatterns += router.urls
-
视图层
from rest_framework.viewsets import GenericViewSet from rest_framework.decorators import action from user.models import User from utils.common_response import APIResponse # # 第一版本 # class UserView(GenericViewSet): # @action(methods=['GET'],detail=False) # def send_msg(self,request,*args,**kwargs): # 保证这个接口的安全(短信轰炸机--》解析出了好多网站的发送短信接口,用多线程) # mobile = request.query_params['mobile'] # if mobile: # user=User.objects.filter(mobile=mobile).first() # if user: # return APIResponse(code=100,msg='手机号存在',exist=True) # else: # return APIResponse(code=100,msg='手机号不存在',exist=True) # else: # return APIResponse(code=888,msg='手机号必填') # 进阶版本 class UserView(GenericViewSet): @action(methods=['GET'],detail=False) def send_msg(self,request,*args,**kwargs): # 保证这个接口的安全(短信轰炸机--》解析出了好多网站的发送短信接口,用多线程) try: # 从地址栏中取出手机号 query_params :queryDict mobile = request.query_params['mobile'] # 取不到值会报错---全局异常 User.objects.get(mobile=mobile) # get 取不到值返回none except Exception as e: raise e # return APIResponse(code=888,msg='手机号必填') return APIResponse(msg='手机号存在')
视图层
def send_sms(self, request, *args, **kwargs):
try:
# 放心大胆写
except Exception as e:
raise e
return APIResponse()
多方式登录接口
视图类
from utils.common_response import APIResponse
from .serializer import UserLoginSerializer
class UserView(GenericViewSet):
@action(methods=['POST'], detail=False)
def login_mul(self, request, *args, **kwargs):
"""
把这个逻辑放在序列化类中
1.取出前端传入的用户名和密码
2.通过用户名和密码去数据库查询用户
3.如果能查到,签发token
4.返回给前端登录成功
"""
# 实例化 序列化类对象时,可以传入context 字典 context 是 视图类和序列化类沟通的桥梁
# 序列化类全局钩子,放入的
# 有了序列化类对象,通过 对象.context 就可以拿到值
ser = self.get_serializer(data=request.data)
ser.is_valid(raise_exception=True) # 执行这句话,会走字段自己的校验,局部钩子,全局钩子
token = ser.context.get('token')
username = ser.context.get('username')
return APIResponse(token=token, username=username) # {code:100,msg:成功,token:aasdfa,username:kimi}
序列化类
import re
from rest_framework import serializers
from .models import User
from rest_framework.exceptions import APIException
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,因为序列化就是校验字段是唯一性,重写把原来的规则去掉"""
username = serializers.CharField()
class Meta:
model = User
# username映射过来,是唯一的,字段自己的校验就过不了,所有要重写这个字段
fields = ['username', 'password'] # 这个序列化类用来校验字段---不做序列化,也不做反序列化
"""
把这个逻辑放在序列化类中
1.取出前端传入的用户名和密码
2.通过用户名和密码去数据库查询用户
3.如果能查到,签发token
4.返回给前端登录成功
"""
# 全局钩子
def validate(self, attrs):
"""attrs 是前端传入的数据,经过 字段自己校验和局部钩子校验过后的数据 {username:kimi,password:123} """
user = self._get_user(attrs)
token = self._get_token(user)
self.context['token'] = token
self.context['username'] = user.username
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-]+)*\.[a-zA-Z0-9]{2,6}$', 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):
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token
腾讯云短信申请
# 发送短信接口,借助于第三方短信平台,收费的
-腾讯云短信
-阿里 大于短信
# 申请微信公众号
# 使用腾讯短信
1.https://cloud.tencent.com,微信扫码登录
2.搜索短信:https://console.cloud.tencent.com/smsv2
3.创建短信签名:公众号注册,提交等待审核
4.创建短信正文模版
5.等待审核
6.发送短信
python---短信
# API SDK
API: 咱们学习过的API接口,写起来比较麻烦,自己分析接口
SDK:集成开发工具包,分语言,java,python,go
使用python 对api进行封装成包
以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
只要官方提供sdk,优先用sdk
pip install tencentcloud-sdk-python
补充
# https://gitee.com/aeasringnar/django-RESTfulAPI/tree/master
# https://gitee.com/aeasringnar
标签:username,短信,登录,接口,路飞,token,user,序列化
From: https://www.cnblogs.com/zhanglanhua/p/17177038.html