Python实战项目6-后端多方式登录接口/手机登录接口

为开源项目共享代码

步骤: 	1先fork开源项目 	2clone下来,修改代码,进行提交 	3提交pr,等作者同意 

Pycharm 使用Git

右键文件会列出Git命令
Python实战项目6-后端多方式登录接口/手机登录接口

登录注册功能分析

多方式登录接口:用户名/手机号/邮箱 + 密码都可以登陆  发送手机验证码接口 (借助于第三方短信平台)  短信登录接口  注册接口 

手机号是否存在接口

校验手机号是否存在
user/urls.py

路由层 from django.urls import path, include from rest_framework.routers import SimpleRouter from . import views  router = SimpleRouter() router.register('user',views.UserView,'user') urlpatterns = [     path('',include(router.urls)) //  ] # urlpatterns += router.urls	 

user/views.py

from rest_framework.viewsets import ViewSet from rest_framework.exceptions import APIException from rest_framework.decorators import action from utils.response import APIResponse from .models import UserInfo class UserView(ViewSet):     @action(methods=['get'], detail=False)     def check_mobile(self, request):         try:             # 如果布报错就说明手机号存在             mobile = request.query_params.get('mobile')             UserInfo.objects.get(mobile=mobile)             return APIResponse('手机号存在')         except Exception as e:             # raise e  也可以直接返抛出异常,就可以被全局异常捕获到             raise APIException('手机号不存在!') 

视图函数模板

from restframework.response import APIresponse def send_sms(self, request, *args, **kwargs):         try:             # 放心大胆写         except Exception as e:             raise e         return APIResponse() 

多方式登录接口

使用用户名/手机号/邮箱+密码登录
发送post请求到后端{"username":"xxx","password":"123"}

# 登录逻辑 1取出前端传入的用户名和密码 2通过用户名和密码去数据库查询 3查到了,签发token 4返回前端  将逻辑放入序列化类中.. 

视图类

  • ser_obj.context >> 序列化类与视图类沟通的桥梁(本质上是个字典)
from rest_framework.viewsets import ViewSet from .serializer import UserMulLoginSerializer, MobileLoginSerializer from rest_framework.decorators import action from utils.response import APIResponse from .models import UserInfo class UserView(ViewSet):     @action(methods=['post'], detail=False, )     def login(self, request):         return self.common_login()               def _get_serializer(self, data): # 因为我们有短信登录和多方式登录,可以将序列化类封装到函数中通过判断获取         # 判断请求方式返回不同的序列化类         res = self.request.META.get('PATH_INFO')         #  PATH_INFO 可以拿到请求的路径信息         if res == '/api/v1/userinfo/user/mobile_login/':             return MobileLoginSerializer(data=data)         return UserMulLoginSerializer(data=data)      def common_login(self):           ser_obj = self._get_serializer(data=self.request.data)         # 执行这句话,会走字段自己的校验,局部钩子,全局钩子         ser_obj.is_valid(raise_exception=True)         token = ser_obj.context.get('token')         # 有了序列化类对象,通过  对象.context 就可以拿到值         icon = ser_obj.context.get('icon')         username = ser_obj.context.get('username')         return APIResponse(token=token, icon=icon, username=username) 

序列化类

from rest_framework import serializers from .models import UserInfo from utils.common_serializer import Verification   class UserMulLoginSerializer(serializers.ModelSerializer, Verification):     # 全局钩子中有很多重复代码,我们直接将其封装到 (多方式登录和手机登录都可以使用)     # utils目录下的common_serializer.py中     username = serializers.CharField()     # 由于序列化类校验时会先走字段自己的校验,Mobile字段我们又设置了unique=True属性     # 所以如果我们请求来到了字段自己的校验就不会通过,我们需要重写该字段      class Meta:         model = UserInfo         fields = ['username', 'password']        def validate(self, attrs):          attrs = self._validate(attrs)         return attrs  # 全局钩子必须返回校验后的数据 如果没有通过序列化类的校验,需抛出异常 我们又封装了全局捕获异常,所以就直接抛出即可 

utils/common_serializer/Verification

import re from django.contrib.auth import authenticate from rest_framework.exceptions import ValidationError,APIException from django.core.cache import cache from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler from user.models import UserInfo class Verification():     def _get_token(self, user_obj):         pay_load = jwt_payload_handler(user_obj)         token = jwt_encode_handler(pay_load)         return token     def _validate(self,attrs):         user_obj = self._get_user(attrs)         token = self._get_token(user_obj)         self.context['token'] = token  # self 是 序列化类对象 所以可以点context传值进去         self.context['username'] = user_obj.username         self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user_obj.icon)         return attrs     def _get_user(self, attrs):         username = attrs.get('username')         password = attrs.get('password')         mobile = attrs.get('mobile')         if mobile:             if not re.match(r'^1[3-9][0-9]{9}$', mobile):                 raise ValidationError('手机号格式输入错误')             code = attrs.get('code')             old_code = cache.get('sms_code_%s' % mobile)             if code == old_code:                 return UserInfo.objects.filter(mobile=mobile).first()             raise APIException('验证码错误')                  if re.match(r'^1[3-9][0-9]{9}$', username):             user_obj = UserInfo.objects.filter(mobile=username).first()             if user_obj.check_password(password) and user_obj:                 return user_obj             raise ValidationError('用户名或密码错误')             # user_obj = authenticate(mobile=username, password=password)         elif re.match(r'^.+@.+$', username):             user_obj = authenticate(email=username, password=password)         else:             user_obj = authenticate(username=username, password=password)         if not user_obj:             raise ValidationError('用户名或密码错误')         return user_obj              

腾讯云短信申请

  • 发送短信接口,借助于第三方短信平台

我们在使用云短信前需要自己申请Vx公众号(个人的即可)

  • 使用腾讯短信

微信扫码登录

  • 搜索短信:
  • 创建短信签名:公众号注册,提交等待审核
  • 创建短信正文模版
  • 等待审核
  • 发送短信(api接口 SDK)

API: 咱们学习过的API接口,写起来比较麻烦,自己分析接口,对上即可
SDK:集成开发工具包,分语言,java,python,go
使用python 对api进行封装成包
以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
pip install tencentcloud-sdk-python

发表评论

相关文章