day08

内容概要

  • 腾讯云短信开发
  • 短信验证码接口
  • 短信登录接口
  • 短信注册接口

腾讯云短信开发

image-20230306183549590

然后去

image-20230306231534604

# -*- coding: utf-8 -*-
import os
import sys
import logging

from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
# 导入对应产品模块的client models。
from tencentcloud.cvm.v20170312 import cvm_client, models

# 导入可选配置类
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
try:
    # 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey。
    # 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中,请参考本文凭证管理章节。
    # 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
    # cred = credential.Credential("secretId", "secretKey")
    cred = credential.Credential(
        os.environ.get("TENCENTCLOUD_SECRET_ID"),
        os.environ.get("TENCENTCLOUD_SECRET_KEY"))
    cred = credential.Credential("SecretId", "SecretKey")

    # 实例化一个http选项,可选的,没有特殊需求可以跳过。
    httpProfile = HttpProfile()
    # 如果需要指定proxy访问接口,可以按照如下方式初始化hp
    # httpProfile = HttpProfile(proxy="http://用户名:密码@代理IP:代理端口")
    httpProfile.protocol = "https"  # 在外网互通的网络环境下支持http协议(默认是https协议),建议使用https协议
    httpProfile.keepAlive = True  # 状态保持,默认是False
    httpProfile.reqMethod = "GET"  # get请求(默认为post请求)
    httpProfile.reqTimeout = 30    # 请求超时时间,单位为秒(默认60秒)
    httpProfile.endpoint = "cvm.ap-shanghai.tencentcloudapi.com"  # 指定接入地域域名(默认就近接入)

    # 实例化一个client选项,可选的,没有特殊需求可以跳过。
    clientProfile = ClientProfile()
    clientProfile.signMethod = "TC3-HMAC-SHA256"  # 指定签名算法
    clientProfile.language = "en-US"  # 指定展示英文(默认为中文)
    clientProfile.httpProfile = httpProfile

    # 实例化要请求产品(以cvm为例)的client对象,clientProfile是可选的。
    client = cvm_client.CvmClient(cred, "ap-shanghai", clientProfile)

    # 打印日志按照如下方式,也可以设置log_format,默认为 '%(asctime)s %(process)d %(filename)s L%(lineno)s %(levelname)s %(message)s'
    # client.set_stream_logger(stream=sys.stdout, level=logging.DEBUG)
    # client.set_file_logger(file_path="/log", level=logging.DEBUG) 日志文件滚动输出,最多10个文件,单个文件最大512MB
    # client.set_default_logger() 去除所有log handler,默认不输出

    # 实例化一个cvm实例信息查询请求对象,每个接口都会对应一个request对象。
    req = models.DescribeInstancesRequest()

    # 填充请求参数,这里request对象的成员变量即对应接口的入参。
    # 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义。
    respFilter = models.Filter()  # 创建Filter对象, 以zone的维度来查询cvm实例。
    respFilter.Name = "zone"
    respFilter.Values = ["ap-shanghai-1", "ap-shanghai-2"]
    req.Filters = [respFilter]  # Filters 是成员为Filter对象的列表

    # python sdk支持自定义header如 X-TC-TraceId、X-TC-Canary,可以按照如下方式指定,header必须是字典类型的
    headers = {
        "X-TC-TraceId": "ffe0c072-8a5d-4e17-8887-a8a60252abca"
    }
    req.headers = headers

    # 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的,headers为可选参数。
    # 返回的resp是一个DescribeInstancesResponse类的实例,与请求对象对应。
    resp = client.DescribeInstances(req)

    # 输出json格式的字符串回包
    print(resp.to_json_string(indent=2))

    # 也可以取出单个值。
    # 你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义。
    print(resp.TotalCount)
except TencentCloudSDKException as err:
    print(err)

把这个cv过去 然后按着步骤来就可以了

短信验证码接口

# 发送验证码
@action(methods=["POST"], detail=False)
def get_code(self, request):
    mobile = request.data.get("mobile")
    code = get_code()
    cache.set("sms_%s" % mobile, code)
    ten_send_sms(mobile, code)
    return APIResponse(msg="发送成功")

把那个发送验证码的封装一下,拿来调用就可以了

短信登录接口

这个登录跟 那个多方式登录都差不多

序列化层

import re
from .models import User
from rest_framework.exceptions import APIException
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

from django.core.cache import cache


class MobilSerializer(serializers.Serializer):
    mobile = serializers.CharField()
    code = serializers.CharField()

    def validate(self, attrs):
        user = self._get_use(attrs)
        # 签发token
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        self.context["username"] = user.username
        self.context["token"] = token
        return attrs

    def _get_use(self, attrs):
        mobile = attrs.get("mobile")
        code = attrs.get("code")
        if not code == cache.get("sms_%s" % mobile, code):
            raise APIException("验证码错误")
        user = User.objects.filter(mobile=mobile).first()
        if not user:
            raise APIException("手机还没有注册")
        return user

视图层

from django.core.cache import cache
from rest_framework.decorators import action
from rest_framework.viewsets import GenericViewSet
from .serializer import UserSerializer, MobilSerializer
from utils import APIResponse
from .models import User
from libs import get_code, ten_send_sms


class UserView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_serializer_class(self):
        # print(self.action, "我是action")  # 只要你继承了ViewSetMixin那么就会有对象就会有action属性,热这个属性就是执行的方法名
        if self.action == "login":
            return super().get_serializer_class()
        elif self.action == "mobile_login":
            return MobilSerializer

    # 手机号验证码登录
    @action(methods=["POST"], detail=False)
    def mobile_login(self, request):
        res = self.get_serializer(data=request.data)
        res.is_valid(raise_exception=True)
        # 避免数据被污染
        username = res.context.get("username")
        token = res.context.get("token")
        return APIResponse(msg="登录成功", data={"username": username, "token": token})

    # 发送验证码
    @action(methods=["POST"], detail=False)
    def get_code(self, request):
        mobile = request.data.get("mobile")
        code = get_code()
        cache.set("sms_%s" % mobile, code)
        ten_send_sms(mobile, code)
        return APIResponse(msg="发送成功")

路由

route.register("userinfo", views.UserView, "userinfo")

短信注册

视图层

class UserView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_serializer_class(self):
        # print(self.action, "我是action")  # 只要你继承了ViewSetMixin那么就会有对象就会有action属性,热这个属性就是执行的方法名
        if self.action == "login":
            return super().get_serializer_class()
        elif self.action == "mobile_login":
            return MobilSerializer
        elif self.action == "register":
            return RegisterSerializer

    @action(methods=["POST"], detail=False)
    def register(self, reqeust):
        res = self.get_serializer(data=reqeust.data)
        res.is_valid(raise_exception=True)
        res.save()
        return APIResponse(msg="注册成功")

序列化层

class RegisterSerializer(serializers.Serializer):
    code = serializers.CharField()
    mobile = serializers.CharField()
    password = serializers.CharField()

    def validate(self, attrs):
        mobile = attrs.get("mobile")
        code = attrs.get("code")
        if not code == cache.get("sms_%s" % mobile, code):
            raise APIException("验证码错误")
        user = User.objects.filter(mobile=mobile).first()
        if user:
            raise APIException("手机号已经注册过了")
        attrs.pop("code")
        attrs["username"] = mobile
        return attrs

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user
posted @ 2023-03-07 00:16  可否  阅读(48)  评论(0)    收藏  举报