day05-前后端项目上传到gitee、后端多方式登录接口、发送短信功能、发送短信封装、短信验证码接口、短信登录接口

1 前后端项目上传到gitee

2 后端多方式登录接口

2.1 序列化类
2.2 视图类
2.3 路由

3 发送短信功能

4 发送短信封装
4.0 目录结构
4.1 settings.py
4.2 sms.py

5 短信验证码接口

6 短信登录接口
6.1 视图类
6.2 序列化类

1 前后端项目上传到gitee

# 我们看到好多开源项目,前后端都在一个仓库中---》为了方便
# 正常咱们开发代码,一个项目一个仓库  # 1 后端仓库创建好了,提交过了---》继续提交git add .git commit -m '完成手机号校验功能'git push origin master# 2 前端创建远程仓库本地按上面命令,提交上即可(配置远程remote地址)

2 后端多方式登录接口

# 分析前端携带的数据:{username:用户名,手机号,邮箱,password:md5(密码)}注册的时候:密码也是md5加密后带过来的我们登录的时候,带的密码是md5加密的---》后端校验通不过# 后端:-request.data中取出来-校验用户名密码是否正确---》逻辑写到 序列类中-配合序列化类---》全局钩子中写逻辑,签发token-返回给前端# 总结:1 序列化类实例化得到对象时要ser=UserLoginSerializer(data=request.data)    data=request.data  不能传给第一个位置2 被 APIResponse 序列化的数据类型,必须是 数字,字符串,列表,字典,不能是其他对象类型3 配置文件中写了个 后台项目地址

2.1 序列化类

from .models import User
from rest_framework import serializers
import re
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
from django.conf import settings# 只用来做校验
class UserLoginSerializer(serializers.Serializer):# 字段自己的校验规则会限制,不通过,因为是unique的username = serializers.CharField()password = serializers.CharField()def validate(self, attrs):# 1 校验用户名密码是否正确user = self._get_user(attrs)# 2 签发tokentoken = self._get_token(user)# 3 把签发的token和username放到context中self.context['username'] = user.usernameself.context['token'] = tokenself.context['icon'] = settings.BACKEND_URL + '/media/' + str(user.icon)# 4 返回attrsreturn attrsdef _get_user(self, attrs):username = attrs.get('username')password = attrs.get('password')if re.match(r'^1[3-9][0-9]{9}$', username):# 因为这个password是明文---》在数据库中存了密文,必须要使用  user.check_password校验用户秘钥# user=User.objects.filter(mobile=username,password=password)user = User.objects.filter(mobile=username).first()elif re.match(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', username):user = User.objects.filter(email=username).first()else:user = User.objects.filter(username=username).first()if user and user.check_password(password):return userelse:raise ValidationError('用户名或密码错误')def _get_token(self, user):payload = jwt_payload_handler(user)token = jwt_encode_handler(payload)return token

2.2 视图类

class UserLoginView(GenericViewSet):serializer_class = UserLoginSerializer# 没有用,就不需要写# queryset = None@action(methods=['POST'], detail=False)def mul_login(self, request, *args, **kwargs):ser = self.get_serializer(data=request.data)# ser=UserLoginSerializer(data=request.data)ser.is_valid(raise_exception=True)username = ser.context.get('username')token = ser.context.get('token')icon = ser.context.get('icon')# icon 必须是字符串形式,不能是对象形式# {code:100,msg:成功,token:asdfasf,icon:asdfasdf,username:asdfasd}return APIResponse(username=username, token=token, icon=icon)# {code:100,msg:成功,token:asdfasf,user:{id:1,username:xxx,icon:ssss}}# return APIResponse(token=token, user=ser.data) # 如果执行ser.data,就会走序列化

2.3 路由

# 127.0.0.1:8000/api/v1/user/login/mul_login/   ---post 请求
router.register('login', UserLoginView, 'login')

3 发送短信功能

# 需要借助于第三方---》腾讯云# python 脚本测试,能够成功发送短信# API和sdk的区别-API: 网络地址,有请求方式,向这个地址按照规则发送请求,就能完成某些操作---》以后只要使用第三方服务,大概率会提供给你api-sdk:集成开发工具包,第三方平台,用不同语言对api接口进行封装---》只要按照它的使用规则---》直接导入使用接口-可能没提供所有语言的sdk,不同语言要单独写-python的形式就是一个 包,把包下载下来-以后使用第三方,如果有sdk,优先用sdk,如果没有,只能用api# 下载sdk
pip install --upgrade tencentcloud-sdk-python

在这里插入图片描述

# -*- coding: utf-8 -*-
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
# 导入对应产品模块的client models。
from tencentcloud.sms.v20210111 import sms_client, models# 导入可选配置类
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfiletry:# 必要步骤:# 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。# 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。# 您也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,# 以免泄露密钥对危及您的财产安全。# SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capicred = credential.Credential("", "")# 实例化一个http选项,可选的,没有特殊需求可以跳过。httpProfile = HttpProfile()# 如果需要指定proxy访问接口,可以按照如下方式初始化hp(无需要直接忽略)# httpProfile = HttpProfile(proxy="http://用户名:密码@代理IP:代理端口")httpProfile.reqMethod = "POST"  # post请求(默认为post请求)httpProfile.reqTimeout = 30  # 请求超时时间,单位为秒(默认60秒)httpProfile.endpoint = "sms.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)clientProfile = ClientProfile()client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)req = models.SendSmsRequest()req.SmsSdkAppId = "1400861098"# 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名# 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看req.SignName = "RoyHuang公众号"# 模板 ID: 必须填写已审核通过的模板 ID# 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看req.TemplateId = "1951470"# 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,,若无模板参数,则设置为空req.TemplateParamSet = ["8888",'10']req.PhoneNumberSet = ["+8613221296955"]# 用户的 session 内容(无需要可忽略): 可以携带用户侧 ID 等上下文信息,server 会原样返回req.SessionContext = ""# 短信码号扩展号(无需要可忽略): 默认未开通,如需开通请联系 [腾讯云短信小助手]req.ExtendCode = ""# 国内短信无需填写该项;国际/港澳台短信已申请独立 SenderId 需要填写该字段,默认使用公共 SenderId,无需填写该字段。注:月度使用量达到指定量级可申请独立 SenderId 使用,详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。req.SenderId = ""resp = client.SendSms(req)# 输出json格式的字符串回包print(resp.to_json_string(indent=2))except TencentCloudSDKException as err:print(err)

4 发送短信封装

4.0 目录结构

tx_sms__init__.pysettings.pysms.py

4.1 settings.py

	SECRET_ID=''SECRET_KEY=''APPID=''SIGN_NAME=''TEMPLATE_ID=''

4.2 sms.py

import random
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from . import settingsimport json# 1 生成一个 固定长度的随机验证码(数字)
def get_code(number=4):code = ''for i in range(number):r = random.randint(0, 9)code += str(r)return code# 2 传入手机号和验证,发送短信功能函数
def send_sms(code, mobile):try:cred = credential.Credential(settings.SECRET_ID, settings.SECRET_KEY)httpProfile = HttpProfile()httpProfile.reqMethod = "POST"  # post请求(默认为post请求)httpProfile.reqTimeout = 30  # 请求超时时间,单位为秒(默认60秒)httpProfile.endpoint = "sms.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)clientProfile = ClientProfile()client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)req = models.SendSmsRequest()req.SmsSdkAppId = settings.APPIDreq.SignName = settings.SIGN_NAMEreq.TemplateId = settings.TEMPLATE_IDreq.TemplateParamSet = [code, '1']req.PhoneNumberSet = ["+86" + mobile]resp = client.SendSms(req)print(resp.to_json_string(indent=2))response_data_dict = json.loads(resp.to_json_string(indent=2))if response_data_dict.get('SendStatusSet')[0].get('Code')=='Ok':return Trueelse:# 失败了,可以拿出message---》正常发送失败return Falseexcept Exception as err:# 发送过程中出了错误,失败return Falseif __name__ == '__main__':print(get_code())

5 短信验证码接口

class MobileView(ViewSet):@action(methods=['POST'], detail=False)def send_sms(self, request, *args, **kwargs):# 1 给谁发,手机号是从前端传入的,{mobile:18923434,code:'验证码'}  ---》我们的:{mobile:18923434}mobile = request.data.get('mobile')# 2 生成数字验证码code = get_code()# 3 数字验证码保存---》保存到哪?后续还能拿到---》放到缓存中---》默认放在内存中cache.set('cache_mobile_%s' % mobile, code)  # key 一定要唯一,后续还能取出来,就用手机号# 4 同步 发送短信---》同步发送--》可能前端会一直等待,耗时# res = send_sms_mobile(code, mobile)# if res:#     return APIResponse(msg='发送成功')# else:#     return APIResponse(code=101, msg='发送失败,请稍后再试')## 5 发送短信--》异步操作,使用多线程,无法知道短信是否成功了,不需要关注是否成功t=Thread(target=send_sms_mobile,args=[code,mobile])t.start()return APIResponse(msg='发送已发送')

6 短信登录接口

# 分析:前端携带的数据---{mobile:11111,code:8888}后端:-取出手机号验证码,验证验证码是否正确,如果正确-签发token-返回给前端

6.1 视图类

class UserLoginView(GenericViewSet):serializer_class = UserLoginSerializer# 没有用,就不需要写# queryset = None@action(methods=['POST'], detail=False)def mul_login(self, request, *args, **kwargs):return self._login(request, *args, **kwargs)@action(methods=['POST'], detail=False)def sms_login(self, request, *args, **kwargs):return self._login(request, *args, **kwargs)def get_serializer_class(self):# 判断,如果是sms_login,返回  短信登录的序列化类,其他情况就返回UserLoginSerializerif self.action == 'sms_login':return SMSLoginSerializerelif self.action == 'mul_login':return UserLoginSerializerelse:return super().get_serializer_class()def _login(self, request, *args, **kwargs):ser = self.get_serializer(data=request.data)  # 序列化类不一样,重写某个方法,实现,不同的请求action,返回的序列化类不一样ser.is_valid(raise_exception=True)username = ser.context.get('username')token = ser.context.get('token')icon = ser.context.get('icon')return APIResponse(username=username, token=token, icon=icon)

6.2 序列化类

class LoginSerializer(serializers.Serializer):def validate(self, attrs):# 1 校验用户名密码是否正确user = self._get_user(attrs)# 2 签发tokentoken = self._get_token(user)# 3 把签发的token和username放到context中self.context['username'] = user.usernameself.context['token'] = tokenself.context['icon'] = settings.BACKEND_URL + '/media/' + str(user.icon)# 4 返回attrsreturn attrsdef _get_user(self, attrs):passdef _get_token(self, user):payload = jwt_payload_handler(user)token = jwt_encode_handler(payload)return token# 只用来做校验
class UserLoginSerializer(LoginSerializer):# 字段自己的校验规则会限制,不通过,因为是unique的username = serializers.CharField()password = serializers.CharField()def _get_user(self, attrs):username = attrs.get('username')password = attrs.get('password')if re.match(r'^1[3-9][0-9]{9}$', username):# 因为这个password是明文---》在数据库中存了密文,必须要使用  user.check_password校验用户秘钥# user=User.objects.filter(mobile=username,password=password)user = User.objects.filter(mobile=username).first()elif re.match(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', username):user = User.objects.filter(email=username).first()else:user = User.objects.filter(username=username).first()if user and user.check_password(password):return userelse:raise ValidationError('用户名或密码错误')class SMSLoginSerializer(LoginSerializer):mobile = serializers.CharField()code = serializers.CharField()def _get_user(self, attrs):mobile = attrs.get('mobile')code = attrs.get('code')# 1 校验code是否正确old_code = cache.get('cache_mobile_%s' % mobile)if old_code == code:# 2 根据手机号,取到用户user = User.objects.filter(mobile=mobile).first()if user:return userelse:raise ValidationError('手机号不存在')else:raise ValidationError('验证码错误')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/158006.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决react使用css module无法重写bootstrap样式的问题

react使用css module虽然能够解决样式污染,但是同时也失去了写css样式的灵活性,特别是:在.module.css文件中当子元素是非变量的静态class类(比如bootstrap), 此时使用css选择器对该子元素的样式不会起作用的 比如下面…

boot分页

List<ElectricDispatchTodoPO> todoList electricDispatchTodoService.queryTodlList(vo, sysStaffVO);// 计算总记录数int total todoList.size();// 如果总记录数大于0PageInfo<ElectricDispatchTodoPO> pageInfo new PageInfo<>();if (total > 0) {…

聚观早报 | “百度世界2023”即将举办;2024款岚图梦想家上市

【聚观365】10月13日消息 “百度世界2023”即将举办 2024款岚图梦想家上市 腾势D9用户超10万 华为发布新一代GigaGreen Radio OpenAI拟进行重大更新 “百度世界2023”即将举办 “百度世界2023”将于10月17日在北京首钢园举办。届时&#xff0c;百度创始人、董事长兼首席执…

科技资讯|9月新能源汽车零售74.3万辆,充电桩迎来发展高峰

据中国乘联会发布的初步数据&#xff0c;中国 9 月份乘用车市场零售 202.8 万辆&#xff0c;同比增长 6%&#xff0c;环比增 6%。今年以来&#xff0c;我国乘用车市场累计零售 1,524 万辆&#xff0c;同比增长 2%。 乘联会预计&#xff0c;9 月份新能源车市场零售 74.3 万辆&a…

创建IDEA模板

将常用的配置文件内容、模板框架等放到IDEA的模板中保存&#xff0c;方便以后使用。以mybatis-config.xml和一个映射文件为例&#xff08;这是我自己学习SSM时用到的&#xff0c;后面学习SpringBoot时发现配置都只需要写到application.yml中就ok了&#xff0c;配置变得非常简单…

Redis的下载与安装

1.redis下载 windows版本下载地址&#xff1a;https://github.com/MSOpenTech/redis/tags 解压后 2.启动redis

TCP/IP(十三)滑动窗口

一 滑动窗口 通信双方要读懂对方的反馈信息,并进行调整 TCP滑动窗口原理终于清楚了 TCP Window Full 和 TCP Zero Window 零窗口通知与窗口探测 "特殊的场景" 1、TCP Window Full 是站在发送端角度说的特点&#xff1a; 表示发送端不能再发数据给对方,除非发送…

使用 Apache Kafka 进行发布-订阅通信中的微服务

发布-订阅消息系统在任何企业架构中都发挥着重要作用&#xff0c;因为它可以实现可靠的集成&#xff0c;而无需紧密耦合应用程序。在解耦的系统之间共享数据的能力并不是一个容易解决的问题。 考虑一家拥有多个使用不同语言和平台独立构建的应用程序的企业。它需要响应地共享数…

小程序使用uni.createAnimation只执行一次的问题

思路&#xff1a; 在页面创建的时候&#xff0c;创建一个临时动画对象调用 step() 来表示一组动画完成通过动画实例的export方法导出动画数据传递给组件的animation属性还原动画页面卸载的时候&#xff0c;清除动画数据 <template><view class"content"&g…

使用hugging face开源库accelerate进行多GPU(单机多卡)训练卡死问题

目录 问题描述及配置网上资料查找1.tqdm问题2.dataloader问题3.model(input)写法问题4.环境变量问题 我的卡死问题解决方法 问题描述及配置 在使用hugging face开源库accelerate进行多GPU训练&#xff08;单机多卡&#xff09;的时候&#xff0c;经常出现如下报错 [E Process…

设计模式_责任链

责任链模式 介绍 设计模式定义案例责任链模式问题 传给 多个可处理人 这多个处理人做成一个链表学生请假条审核 上课老师&#xff08;3天权限&#xff09; 班主任 &#xff08;5天权限&#xff09; 校长 &#xff08;30天权限&#xff09; 问题堆积在哪里解决办法进一步优…

k8s 1.28版本二进制安装

本文目录 二进制安装Kubernetes&#xff08;k8s&#xff09;v1.28.0介绍1.环境1.0.环境准备1.Linux网卡没有eth0显示ens33或者其它&#xff08;以ens33为例&#xff09;方法一&#xff1a;修改网卡配置方法二&#xff1a;重新安装机器(本文为虚拟机) 2.克隆的虚拟机&#xff0c…

ExcelBDD Python指南

在Python里面支持BDD Excel BDD Tool Specification By ExcelBDD Method This tool is to get BDD test data from an excel file, its requirement specification is below The Essential of this approach is obtaining multiple sets of test data, so when combined with…

《向量数据库指南》——宏观解读向量数据库Milvus Cloud

宏观解读向量数据库 如今,强大的机器学习模型配合 Milvus 等向量数据库的模式已经为电子商务、推荐系统、语义检索、计算机安全、制药等领域和应用场景带来变革。而对于用户而言,除了足够多的应用场景,向量数据库还需要具备更多重要的特性,包括: 可灵活扩展、支持调参:当…

微服务13-Seata的四种分布式事务模式

文章目录 XA模式实现XA模式 AT模式AT模式的脏写问题&#xff08;对同数据并发写的问题&#xff09;其他事务不获取全局锁的一个情况&#xff08;AT模式写隔离的实现&#xff09;实现AT模式 TCC模式TCC实现我们怎么样去判断是否空回滚和业务悬挂&#xff1f;业务分析 Saga模式总…

[elasticsearch]使用postman来查询数据

最近需要debug程序&#xff0c;debug的时候需要查找elasticsearch里面的数据是否正确。 第一步建立一个post请求&#xff0c;并按照图下的方式填上ur和参数&#xff1a; 发送post请求&#xff0c;url为&#xff1a; http://ip:port/index_name/_search我这里查询的是title字…

k8s使用

一、Kubernetes好处 ​ kubernetes&#xff0c;是一个全新的基于容器技术的分布式架构领先方案&#xff0c;是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本&#xff0c;于2014年9月发布第一个版本&#xff0c;2015年7月发布第一个正式版本。 ​ kubernetes的本质…

常见的作物模型有哪些?DSSAT模型、APSIM模型、WOFOST模型与PCSE模型等应用

目录 ①最新DSSAT作物模型建模方法及应用 ②基于Python语言快速批量运行DSSAT模型及交叉融合、扩展应用 ③R语言与作物模型&#xff08;以DSSAT模型为例&#xff09;融合应用 ④WOFOST模型与PCSE模型应用 ⑤基于R语言APSIM模型进阶应用与参数优化、批量模拟 ⑥遥感数据与…

网工配置命令基础总结(2)----VRRP配置

目录 1.配置VRRP主备备份 2.配置VRRP负载分担 3.配置VRRP域BFD联动实现快速切换 VRRP 虚拟路由冗余协议 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;通过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟网关设备的 IP 地址作为用户的默认…

内部类概述

一、内部类 1.内部类概述 2.内部类的四种实现形式 1.成员内部类 public class Outer {private int age99;public static String a;//成员内部类public class Inner{private int age88;private String name; // public static String school; //jdk 16开始才支持定义静态…