腾讯云短信

腾讯云短信介绍和申请

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
# 使用第三方短信接口 # 注册一个个人公众号---》实名认证 -需要没有注册过的邮箱 # 使用腾讯云短信 1 创建短信签名 -选择公众号截图 2 创建短信正文模版 -创建一个模板 3 等待审核 4 发送短信---》代码发送 -sdk v2 老一些 v3 新的 # 什么是api接口,什么是sdk -SDK一般指软件开发工具包,第三方平台提供的通过相应语言写的包 -咱们只需要集成到项目中, 包.方法 -使用简单 -问题是:有的语言没有sdk -api接口:发送http请求,携带相关数据,调用,通用跟语言没关系

腾讯短信功能二次封装

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
# 腾讯云官方 -短信申请:申请签名,申请模板 -使用官方提供的sdk或者api发送短信 -如果没有sdk就是用api调用 -现在有sdk,优先使用sdk,简单---》不同语言封装的包,直接调用包的方法就可以完成相关操作 - 2.0版本的sdk,3.0版本的sdk -安装3.0的sdk:pip install tencentcloud-sdk-python # 腾讯云所有的功能都集成到这个包中了 -使用:https://cloud.tencent.com/document/product/382/43196#.E9.80.9A.E8.BF.87-pip-.E5.AE.89.E8.A3.85.EF.BC.88.E6.8E.A8.E8.8D.90.EF.BC.89 -安装2.0的sdk:pip install qcloudsms_py # 腾讯云短信功能在这个包中 -使用:https://cloud.tencent.com/document/product/382/11672

image-20220712120354302

腾讯云短信再drf中的使用

1 封装v2版本

init.py

复制代码
  • 1
from .sms import get_code,send_sms_v2

settings.py

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
# 短信应用 SDK AppID APPID = # SDK AppID 以1400开头 # 短信应用 SDK AppKey APPKEY = "" # 需要发送短信的手机号码 # 短信模板ID,需要在短信控制台中申请 TEMPLATE_ID = 1470213 # NOTE: 这里的模板 ID`7839` 只是示例,真实的模板 ID 需要在短信控制台中申请 # 签名 SMS_SIGN = "咋啦叭呼" # NOTE: 签名参数使用的是`签名内容`,而不是`签名ID`。这里的签名"腾讯云"只是示例,真实的签名需要在短信控制台中申请

sms.py

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
# 生成随机n位验证码的函数 import random from qcloudsms_py import SmsSingleSender from qcloudsms_py.httpclient import HTTPError from . import settings # 使用相对导入 def get_code(n=4): code = '' for i in range(n): code += str(random.randint(0, 9)) return code # 发送短信的函数 def send_sms(phone, code): phone_numbers = [phone, ] ssender = SmsSingleSender(settings.APPID, settings.APPKEY) params = [code, '1'] # 当模板没有参数时,`params = []` try: result = ssender.send_with_param(86, phone_numbers[0], settings.TEMPLATE_ID, params, sign=settings.SMS_SIGN, extend="", ext="") except Exception as e: return False return True if __name__ == '__main__': print(get_code())

2 封装v3版本

init.py

复制代码
  • 1
from .sms import get_code,send_sms_v2

settings.py

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
SECRET_ID='AKIDZL2jO2WtBOWaXPE5qV9iKtPvRrCQZiiY' SECRET_KEY='kKl5FF6oNvLZaR5WklZAZllY9XkneIl2' APPID = '1400705789' # SDK AppID 以1400开头 TEMPLATE_ID = '1470213' # 签名 SMS_SIGN = "咋啦叭呼" ### v3版本的APPID TEMPLATE_ID 都必须使用str类型,数字类型报错

sms.py

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
# 生成随机n位验证码的函数 import random from qcloudsms_py import SmsSingleSender from qcloudsms_py.httpclient import HTTPError from . import settings # 使用相对导入 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 HttpProfile from . import settings def get_code(n=4): code = '' for i in range(n): code += str(random.randint(0, 9)) return code # 发送短信的函数 def send_sms(phone, code): try: cred = credential.Credential(settings.SECRET_ID, settings.SECRET_KEY) httpProfile = HttpProfile() httpProfile.reqMethod = "POST" httpProfile.reqTimeout = 30 httpProfile.endpoint = "sms.tencentcloudapi.com" clientProfile = ClientProfile() clientProfile.signMethod = "TC3-HMAC-SHA256" clientProfile.language = "en-US" clientProfile.httpProfile = httpProfile client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile) req = models.SendSmsRequest() req.SmsSdkAppId = settings.APPID req.SignName = settings.SMS_SIGN req.TemplateId = settings.TEMPLATE_ID req.TemplateParamSet = [code, '5'] req.PhoneNumberSet = ["+86" + phone, ] req.SessionContext = "" req.ExtendCode = "" req.SenderId = "" resp = client.SendSms(req) # print(resp.to_json_string(indent=2)) return True except TencentCloudSDKException as err: # print(err) return False

3 短信验证码接口

复制代码
  • 1
  • 2
# post get 我选择用get # 前端传入手机号,调用发送短信函数,完成发送短信

路由

复制代码
  • 1
  • 2
# 127.0.0.1:8000/api/v1/user/sms/send_sms router.register('sms', SMSView, 'sms')

视图类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
# from libs import tencent_sms_v2 as tencent_sms from libs import tencent_sms_v3 as tencent_sms import re class SMSView(ViewSet): @action(methods=['GET'], detail=False) def send_sms(self, request): mobile = request.query_params.get('mobile') if mobile and re.match(r'^1[3-9][0-9]{9}$', mobile): code = tencent_sms.get_code() res = tencent_sms.send_sms(mobile, code) if res: return APIResponse() else: raise APIException(detail='发送短信失败') else: raise APIException(detail='手机号有误')

4 短信登录接口

复制代码
  • 1
# 前端传入的格式---{mobile:12334455,code:8888}

路由

复制代码
  • 1
router.register('sms', SMSView, 'sms')

视图类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
class LoginView(GenericViewSet): queryset = User.objects.all() serializer_class = MulLoginSerializer def common_login(self, request): ser = self.get_serializer(data=request.data, context={'request': request}) ser.is_valid(raise_exception=True) token = ser.context.get('token') icon = ser.context.get('icon') return APIResponse(token=token, icon=icon) # 重写这个方法get_serializer_class,返回什么序列化类,当前用的序列化类就是哪个 def get_serializer_class(self): # 方式一 :通过请求路径来判断,可以 # if 'mul_login' in self.request.path: # return self.serializer_class # else: # return 序列化类 # 方式二:通过action判断 if self.action =='sms_login': return SMSLoginSerializer else: return self.serializer_class @action(methods=['POST'], detail=False) def mul_login(self, request): return self.common_login(request) @action(methods=['POST'], detail=False) def sms_login(self, request): return self.common_login(request)

序列化类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
class SMSLoginSerializer(serializers.ModelSerializer): code = serializers.CharField() # code不是User表的字段,所以要重写code class Meta: model = User fields = ['mobile', 'code'] def _check_user(self, attrs): mobile = attrs.get('mobile') code = attrs.get('code') # 校验code对不对?从缓存中取出来 old_code = cache.get('sms_cache_%s' % mobile) # 取出来,立马失效 cache.set('sms_cache_%s' % mobile,'') if old_code == code: # 万能验证码 user = User.objects.filter(mobile=mobile).first() if user: return user else: raise APIException(detail='用户不存在') else: raise APIException(detail='验证码错误') def _get_token(self, user): payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return token def validate(self, attrs): # 在全局钩子中,校验用户是否登录成功,如果登录成功直接签发token # 1 手机号得到user user = self._check_user(attrs) # 2 user签发token---》签发token token = self._get_token(user) # 3 把token放到 self 对象中得context属性中 self.context['token'] = token host = self.context.get('request').META['HTTP_HOST'] self.context['icon'] = 'http://%s/media/%s' % (host, str(user.icon)) return attrs

5 短信注册接口

复制代码
  • 1
# 前端传入数据----》{mobile:1983334,password:123,code:8888}

视图类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
class UserView(GenericViewSet, CreateModelMixin): serializer_class = UserSerializer queryset = User.objects.all() def create(self, request, *args, **kwargs): super().create(request, *args, **kwargs) return APIResponse(msg='注册成功')

序列化类

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
class UserSerializer(serializers.ModelSerializer): code = serializers.CharField(write_only=True) # code不是User表的字段,所以要重写code class Meta: model = User fields = ['mobile', 'password', 'code'] extra_kwargs = {'password': {'write_only': True}} def validate(self, attrs): # 1 校验code是否正确 mobile = attrs.get('mobile') code = attrs.get('code') old_code = cache.get('sms_cache_%s' % mobile) if not code == old_code: raise APIException(detail='验证码错误') # 2 手机号是否被注册过 if User.objects.filter(mobile=mobile).first(): raise APIException(detail='该手机号已经被注册') # 3 入库前准备---》code字段从attrs中剔除,username必填,手机号就是用户名 attrs.pop('code') attrs['username'] = mobile return attrs def create(self, validated_data): # 因为新增用户,是用create_user新增的,不是使用create新增的 user = User.objects.create_user(**validated_data) return user

路由

复制代码
  • 1
router.register('register', UserView, 'register')
posted @   马氵寿  阅读(114)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开