腾讯云短信

2022/7/12 23:23:33

本文主要是介绍腾讯云短信,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

腾讯云短信介绍和申请

# 使用第三方短信接口

# 注册一个个人公众号---》实名认证
	-需要没有注册过的邮箱

# 使用腾讯云短信
	1 创建短信签名
    	-选择公众号截图

	2 创建短信正文模版
		-创建一个模板
	3 等待审核

	4 发送短信---》代码发送
    	-sdk  v2 老一些
        	  v3 新的
# 什么是api接口,什么是sdk
	-SDK一般指软件开发工具包,第三方平台提供的通过相应语言写的包
    	-咱们只需要集成到项目中,     包.方法  
        -使用简单
        -问题是:有的语言没有sdk
    -api接口:发送http请求,携带相关数据,调用,通用跟语言没关系

腾讯短信功能二次封装

# 腾讯云官方
	-短信申请:申请签名,申请模板
    -使用官方提供的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

from .sms import get_code,send_sms_v2

settings.py

# 短信应用 SDK AppID
APPID =   # SDK AppID 以1400开头
# 短信应用 SDK AppKey
APPKEY = ""
# 需要发送短信的手机号码

# 短信模板ID,需要在短信控制台中申请
TEMPLATE_ID = 1470213  # NOTE: 这里的模板 ID`7839` 只是示例,真实的模板 ID 需要在短信控制台中申请
# 签名
SMS_SIGN = "咋啦叭呼"  # NOTE: 签名参数使用的是`签名内容`,而不是`签名ID`。这里的签名"腾讯云"只是示例,真实的签名需要在短信控制台中申请

sms.py

# 生成随机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

from .sms import get_code,send_sms_v2

settings.py

SECRET_ID='AKIDZL2jO2WtBOWaXPE5qV9iKtPvRrCQZiiY'
SECRET_KEY='kKl5FF6oNvLZaR5WklZAZllY9XkneIl2'


APPID = '1400705789'  # SDK AppID 以1400开头
TEMPLATE_ID = '1470213'
# 签名
SMS_SIGN = "咋啦叭呼"


### v3版本的APPID  TEMPLATE_ID  都必须使用str类型,数字类型报错

sms.py

# 生成随机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 短信验证码接口

# post  get  我选择用get
# 前端传入手机号,调用发送短信函数,完成发送短信

路由

# 127.0.0.1:8000/api/v1/user/sms/send_sms
router.register('sms', SMSView, 'sms')

视图类

# 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 短信登录接口

# 前端传入的格式---{mobile:12334455,code:8888}

路由

router.register('sms', SMSView, 'sms')

视图类

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)

序列化类

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 短信注册接口

# 前端传入数据----》{mobile:1983334,password:123,code:8888}

视图类

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='注册成功')

序列化类

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

路由

router.register('register', UserView, 'register')


这篇关于腾讯云短信的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程