立即注册
Django项目--路飞学城项目04
主要内容
# 登录注册功能
# 接口分析
-1 账号密码登录
-多方式登录接口
-校验手机号是否存在接口 (短信登录和注册,都需要校验手机号是否存在)
-2 短信登录
-发送短信接口
-阿里短信
-腾讯短信平台(以它为例)
-短信登录接口
-3 短信注册
-短信注册接口
1 登录注册页面(前端)
# 要点:
1.以模态框的形式弹出 登录与注册页面 (页面绝对定位 + 覆盖页面的 css样式)
2.点击关闭按钮,存在子组件向父组件通信 (通过自定义事件,子组件触发父组件的事件执行)
X
1.1 Login.vue
登录
{{ sms_interval }}
登录
1.2 Register.vue
{{ sms_interval }}
注册
立即登录
1.3 Header.vue
老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活
2 多方式登录接口
# 使用用户名,邮箱,手机号+密码登录
{username:lqz/132834355/33@qq.com,password:12345}
class LoginView(ViewSet):
def login(self, request):
# 逻辑写在序列化类中
# 1.用if判断的形式,返回数据
# if ser.is_valid():
# token = ser.context.get('token')
# username = ser.context.get('user').username
# return APIResponse(msg='登录成功', token=token, username=username)
# else:
# # return APIResponse(code=101, msg=ser.errors)
# return APIResponse(code=101, msg='用户名或密码错误')
# 2.以序列化器校验 抛异常的形式 返回 (更简洁和常用)
ser.is_valid(raise_exception=True)
token = ser.context.get('token')
username = ser.context.get('user').username
return APIResponse(msg='登录成功', token=token, username=username)
# 序列化类
# 用来: 反序列化,验证前端传入的字段是否合法
class LoginSerializer(serializers.ModelSerializer):
# 坑
'''
username:由于映射了User表的Username,自己有规则,unique=True
username字段自己的校验,会走unique,会去数据库查是否有这个用户,如果有,直接抛异常
故重写这个字段,不设置规则
'''
username = serializers.CharField(max_length=16, min_length=3)
class Meta:
model = models.User
fields = ['username', 'password']
def validate(self, attrs):
'''
1 根据用户名(手机号,邮箱)获取用户
2 如果用户存在,签发token
3 把token放到序列化类的对象中
'''
user = self._get_user(attrs)
token = self._get_token(user)
# 上下文,是个字典
self.context['token']=token
self.context['username']=user.username
return attrs
def _get_user(self, attrs): # '_'表示不是私有,但尽量只给内部用
username = attrs.get('username')
password = attrs.get('password')
# 多种登录方式,正则匹配,如果是手机号根据手机号查。。。
# ^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$
if re.match(r'^1[3-9][0-9]{9}$', username):
user=models.User.objects.filter(mobile=username).first()
# elif re.match(r'[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$',username):
elif re.match(r'^.+@.+$',username):
user = models.User.objects.filter(email=username).first()
else:
user = models.User.objects.filter(username=username).first()
if user and user.check_password(password):
return user
else:
raise ValidationError('用户名或密码错误')
def _get_token(self, user):
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token
3 手机号是否存在接口
class MobileView(ViewSet):
# api/v1/user/mobile/?mobile=12334454
# url_path的作用,自动生成的url路径,默认为空,则以函数名为路径
# @action(methods=['GET'], detail=False,url_path='mobile')
# def check_mobile(self, request):
@action(methods=['GET'], detail=False)
def mobile(self, request):
mobile = request.query_params.get('mobile')
try:
models.User.objects.get(mobile=mobile)
except Exception:
raise APIException('手机号不存在')
return APIResponse(is_exisit=True)
4 腾讯云短信开发
# 申请公众号
-一个邮箱只能注册一个(公众号和小程序)
-https://mp.weixin.qq.com/ 小程序和公众号放到一起了
-按照流程一步步注册
-登录,进入到账号详情
# 集成腾讯短信服务---》按照文档操作
# https://cloud.tencent.com/product/sms
# 注册--》登录---》短信服务
# https://console.cloud.tencent.com/smsv2/csms-template
# 使用步骤
1.创建短信签名
2.创建短信正文模板
等待审核
3.创建应用
4.发送短信
# 刚申请,送100条
# API和SDK的区别
-API:指一堆接口,http/https接口---》写起来比较麻烦
-sdk:使用不同语言基于这些接口封装的代码,java,python,nodejs版本sdk
-python的sdk:V2版本,V3版本
-咱们用V2:qcloudsms_py,只用来发短信
-https://cloud.tencent.com/document/product/382/11672
-新版本V3:tencentcloud-sdk-python,不仅包含了短信功能,还包含了其他腾讯云功能:对象存储...
-https://cloud.tencent.com/document/product/382/56059
-第三方服务肯定会有api,sdk看公司情况
-支付宝支付-->有api,但是没有sdk(第三方
4.1 腾讯云v2.0 单发短信
from qcloudsms_py import SmsSingleSender
from qcloudsms_py.httpclient import HTTPError
# 短信应用 SDK AppID
appid = 1400000000 # SDK AppID 以1400开头
# 短信应用 SDK AppKey
appkey = "fd972f6d5a15add46de47b50b8dbe930"
# 需要发送短信的手机号码
phone_numbers = ["18953670000", ]
# 短信模板ID,需要在短信控制台中申请
template_id = 1049981 # NOTE: 这里的模板 ID`7839` 只是示例,真实的模板 ID 需要在短信控制台中申请
# 签名
sms_sign = "小猿取经" # NOTE: 签名参数使用的是`签名内容`,而不是`签名ID`。这里的签名"腾讯云"只是示例,真实的签名需要在短信控制台中申请
ssender = SmsSingleSender(appid, appkey)
params = ["5678", '3'] # 当模板没有参数时,`params = []`
try:
result = ssender.send_with_param(86, phone_numbers[0],
template_id, params, sign=sms_sign, extend="", ext="")
except HTTPError as e:
print(e)
except Exception as e:
print(e)
print(result)
4.2 腾讯云v3.0 单发短信
# -*- 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 HttpProfile
try:
# 必要步骤:
# 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
# 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
# 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
# 以免泄露密钥对危及你的财产安全。
# CAM密匙查询: https://console.cloud.tencent.com/cam/capi
cred = credential.Credential("密钥id", "密钥key")
# cred = credential.Credential(
# os.environ.get(""),
# os.environ.get("")
# )
# 实例化一个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()
clientProfile.signMethod = "TC3-HMAC-SHA256" # 指定签名算法
clientProfile.language = "en-US"
clientProfile.httpProfile = httpProfile
# 实例化要请求产品(以sms为例)的client对象
# 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量
client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)
# 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
# 你可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置
# 属性可能是基本类型,也可能引用了另一个数据结构
# 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明
req = models.SendSmsRequest()
# 基本类型的设置:
# SDK采用的是指针风格指定参数,即使对于基本类型你也需要用指针来对参数赋值。
# SDK提供对基本类型的指针引用封装函数
# 帮助链接:
# 短信控制台: https://console.cloud.tencent.com/smsv2
# sms helper: https://cloud.tencent.com/document/product/382/3773
# 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666
req.SmsSdkAppId = "1400634441"
# 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看
req.SignName = "靡克世界"
# 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper]
req.ExtendCode = ""
# 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回
req.SessionContext = "xxx"
# 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper]
req.SenderId = ""
# 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
# 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
req.PhoneNumberSet = ["+8618280490000"]
# 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看
req.TemplateId = "1306372"
# 模板参数: 若无模板参数,则设置为空
req.TemplateParamSet = ["666666"]
# 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的。
# 返回的resp是一个DescribeInstancesResponse类的实例,与请求对象对应。
resp = client.SendSms(req)
# 输出json格式的字符串回包
print(resp.to_json_string(indent=2))
except TencentCloudSDKException as err:
print(err)