【Django-Vue】手机号是否存在接口 多方式登录接口 腾讯云短信介绍和申请 api与sdk

昨日回顾

# 你的电脑上装git软件,公司远程仓库
	-gitee
    -gitlab
# 如何搭建:https://zhuanlan.zhihu.com/p/413217715

image-20221110084824290

# 1 git介绍,安装
	-版本管理软件:代码的版本管理和协同开发【多人开发同一个项目,代码合并】
    -官网下载安装
    
# 2 git ,gitlab,gitee,github
	-git软件
    -gitlab,gitee,github:远程仓库
    
# 3 svn和git区别
	-svn集中式管理,没有网络没有服务的,版本管理用不了
    -git分布式管理,没有网络,没有远程仓库,做版本管理没有问题
# 4 git工作流程
	-工作区
    -暂存区
    -版本库
    -远程仓库
    
    
# 5 常用命令
	-git init
    -git add .
    -git commit -m '注释'
    -git status
    -git log
    -git reflog
    -设置用户邮箱和名字的
    	-gitee远程仓库,你当时设置的邮箱如果跟gitee注册邮箱不一样,显示头像不一样
        -gitee设置邮箱公开
        
        
# 6 git过滤文件
	仓库路径下 .gitignore,在文件中配置忽略文件
    文件名
    文件夹名
    *.py
    *.p?
    /文件名
    /文件夹名
    
    
    # 空文件夹不会被git管理
    # 最开始没被版本管理之前就要忽略文件
    
# 7 git多分支
	-master:主分支操作,只用来做发布版本
    -master,dev,bug
    -分支创建
    -切换
    -查看
    -删除
    -合并
    -查看远程仓库和本地仓库的分支:git branch -a
    
# 8 远程仓库 :gitee,gitlab
	-创建空仓库     开源协议
    -把本地仓库代码,提交到远程仓库
    -git remote add origin 地址
    -git pull origin master
    -git push origin master
    
# 9 ssh操作
	-生成公钥私钥
    -公钥配置在远程仓库
    -免密操作
# 10 协同开发
	-多个人同时开发一个项目
    -普通开发者:clone下来----》
    -仓库创建者:本地提交上去---》加成员---》
    
    
# 11 冲突出现和解决
	-多人在同一分支开发
    -分支合并
# 12  线上分支合并
	-线下分支合并 merge
    -线上分支合并:提交申请:pr,mr
# 13 pycharm操作git 
	-所有的git操作都能通过 点点点 实现
    -add
    -commit
    -push
    -pull
    -查看变化
    
    
# 14 为开源项目贡献代码
	先fork项目,你仓库有,你改的你的,提交pr
    
    
# 15 git面试题
# 前端新建 四个组件:1个页面组件[HomeViwe]3个小组件

# 对接轮播图接口

今日内容

0 登录注册功能设计

# 后端接口
	1 账号/手机号/邮箱+密码登录接口
    2 手机号+验证码登录接口
    3 发送手机验证码接口  (第三方发送短信)
    4 注册接口--》手机号,验证码,密码
    5 判断手机号是否存在接口

登录原型图:

image-20230302202330234

注册原型图:

image-20230302202503171

1 短信登录接口

# 接口地址
http://127.0.0.1:8000/api/v1/user/userinfo/send_sms/  # get请求

# 模板
   def send_sms(self, request, *args, **kwargs):
        try:
            # 放心大胆写
        except Exception as e:
            raise e
        return APIResponse()

视图类

通用写法(视图类中写try-except):

class UserView(GenericViewSet):
    @action(methods=['GET'], detail=False)  # 保证这个接口的安全(短信轰炸机--》解析出了好多网站的发送短信接口,用多线程)
    def send_sms(self, request, *args, **kwargs):
        try:
            # 从地址栏中取出手机号  query_params :queryDict
            mobile = request.query_params['mobile']
            User.objects.get(mobile=mobile)
        except Exception as e:
            raise e
            # return APIResponse(code=777,msg='手机号不存在')
        return APIResponse(msg='手机号存在')

后续可以自己写异常类,在视图抛出各种异常。### 视图类

2 多方式密码登录接口

# 登录注册
	1 多方式登录 【用户名、邮箱、手机号+密码】
    2 验证码登录
    3 发送验证码
    4 校验手机号是否存在
    5 手机号注册接口
    
# 接口漏洞
	短信轰炸机
    
# 多方式登录
	-{username:用户名/邮箱/手机号,password:123}---->post请求
    -之前写的逻辑,校验用户,是写在视图类的方法中
    -新方法:把逻辑写在序列化类中

使用action装饰器将路由进行区分。

image-20230302215958332

查询条件比较复杂有三个:用户名/邮箱/手机

新写法,在序列化类中写逻辑:
这个序列化类只用来做多方式登录的校验。它不做序列化,也不做反序列化。因为这是一个登录接口。

如果校验不通过直接抛异常:

image-20230302220555895

校验通过之后要签发token,但是签发token的代码也放在序列化类。

返回token:

image-20230302220846730

执行is_valid会执行字段自己的校验规则、局部钩子、全局钩子。
所以我们在序列化类的全局钩子中写代码即可。

image-20230303113628736

在序列化类中写两个方法:_get_user()_get_token()将代码进行拆分。可以注意到方法名字的前面加入了单下划线。这是约定俗成的,意思是这些方法只在类中用,外部不要调用这些方法。

_get_user:

image-20230303120821809

_get_token:image-20230303120646837

序列化类初始化时自动创建一个context属性,这是一个字典(上下文)。通过这个字典可以实现视图类和序列化类数据的交换。这样做的好处是避免属性的冲突,比如序列化类和视图恰好定义了相同的属性名。

postman测试接口:

image-20230303113931338

查看报错:

image-20230303113956039

这个报错是因为序列化类做了字段的映射,模型类中有字段自己的校验规则。这个字段自己的校验规则无法通过,所以报错。

发送post请求时,序列化类认为你要存数据,会触发字段自己的校验规则。这个校验规则是检验这个字段username在表中是不是唯一的。由于是登录,你上传的用户名显然和数据库存放的用户名是一样的,所以字段自己的校验规则都过不去,直接抛出异常。

重写字段的校验规则:

image-20230303114210519

二维码登录:
带着本地的token向服务器发请求。

视图类

class UserView(ViewSetMixin, GenericAPIView):
    serializer_class = UserLoginSerializer
    queryset = User.objects.all().filter(is_active=True)
    @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')  # ser.context是什么先不着急
        username = ser.context.get('username')
        return APIResponse(token=token, username=username)  # {code:100,msg:成功,token:aasdfa,username:lqz}

序列化类

from .models import User
from rest_framework import serializers
import re
from rest_framework.exceptions import APIException, ValidationError
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']  # 这个序列化类用来校验字段---不做序列化,也不做反序列化

    # 全局钩子
    def validate(self, attrs):
        '''
         把这个逻辑放在序列化类中
         1 取出前端传入的用户名和密码
         2 通过用户名和密码去数据库查询用户
         3 如果能查到,签发token
         4 返回给前端登录成功
        '''
        # attrs 是前端传入的数据,经过 字段自己校验和局部钩子校验过后的数据   {username:lqz,password:123}
        user = self._get_user(attrs)
        token = self._get_token(user)
        # 把用户名,和token放到ser的 context中
        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

image-20230303112909993

路由

from django.contrib import admin
from django.urls import path, re_path
from home import views
from django.views.static import serve
from django.conf import settings
from . import views

from rest_framework.routers import SimpleRouter

router = SimpleRouter()
# 127.0.0.1:8080/api/v1/userinfo/user/mul_login
router.register('user', views.UserView, 'user')

urlpatterns = [
]
urlpatterns += router.urls

3 腾讯云短信介绍和申请

# 咱们要写发送短信接口,我们要发短信,借助于短信运营商 
 	-腾讯云短信
    -阿里云短信

# 腾讯云开放平台,有很多开放的接口供咱们使用,咱们用的是短信
	-注册平台---》找到短信
    -https://console.cloud.tencent.com/smsv2

    
# 使用腾讯短信
	-https://cloud.tencent.com,微信扫码登录
    -搜索短信:https://console.cloud.tencent.com/smsv2
    - 创建短信签名:公众号注册,提交等待审核
	- 创建短信正文模版
	-等待审核
	-发送短信
    	python 代码发送短信 
    
    
    
# 申请使用腾讯云短信:
	 1.微信扫码登录
    	-https://cloud.tencent.com,
     2.-搜索短信:         
    		-https://console.cloud.tencent.com/smsv2
     3. 创建签名:使用公众号申请
    	-网站:备案:工信部备案
        -申请个人一个公众号:
        	-https://mp.weixin.qq.com/
        -等审核通过
    4. 申请模板:发送短信的模板 {1}  {2} 后期用代码填上
    
    5. 免费赠送100条
        
    6. 代码发送短信:参照文档写代码:https://cloud.tencent.com/document/product/382/13444
    	-v2 老一些
        -v3 最新

image-20221110121519296

image-20221110120341171

3.1api与sdk

# API文档
	-之前学的接口文档的概念
    -使用api调用,比较麻烦,固定输入,接受固定的返回
    -使用postman都可以测试,携带你的认证的秘钥。
    
# SDK:Software Development Kit 软件开发工具包
	-分语言,java,python,go..
    -基于API,使用某个编程语言封装的包
    -例如python:pip install 包
    	-包.发短信(参数)
    -以后我们只需要,安装包,导入包,包名.发送短信,传入参数,就可以发送了
   -一般厂商都会提供各大主流语言的sdk

# SDK安装
- 只要官方提供sdk,优先用sdk
	pip install tencentcloud-sdk-python

# 腾讯短信sdk使用步骤
    1 已开通短信服务,创建签名和模板并通过审核    # 开了
    2 如需发送国内短信,需要先 购买国内短信套餐包。 #赠送了
    3 已准备依赖环境:Python 2.7 - 3.6 版本。    #我们有
    4 已在访问管理控制台 >API密钥管理页面获取 SecretID 和 SecretKey。
        SecretID 用于标识 API 调用者的身份。
        SecretKey 用于加密签名字符串和服务器端验证签名字符串的密钥,SecretKey 需妥善保管
    5 短信的调用地址为sms.tencentcloudapi.com。

补充

# https://gitee.com/aeasringnar/django-RESTfulAPI/tree/master
# https://gitee.com/aeasringnar

练习

# 练习使用pycharm操作git
# 手机号是否存在
# 多方式登录接口
# 注册公众号
# 申请腾讯短信
-------------------
# 使用sdk发送一下短信试试
# http 和https的区别?
	https=http+ssl
posted @ 2023-03-03 14:57  passion2021  阅读(40)  评论(0编辑  收藏  举报