发送短信验证码的功能开发
目录
1.注册容联云账号
1.1 注册账号
https://www.yuntongxun.com/user/login
1.2 登录即可看到开发者账号信息
1.3 添加测试账号
2.使用容联云发送代码测试
在libs/rl_sms.py
中写短信发送代码
'''1. 安装容联云sdk'''
pip install ronglian_sms_sdk
# 免费测试文档地址:https://doc.yuntongxun.com/p/5a531a353b8496dd00dcdfe2
'''2. 短信发送代码'''
from ronglian_sms_sdk import SmsSDK
accId = '8a216da8747ac98201749c0de38723b7'
accToken = '86072b540b4648229b27400414150ef2'
appId = '8a216da8747ac98201749c0de45123be'
def send_message(phone, datas):
sdk = SmsSDK(accId, accToken, appId)
tid = '1' # 测试模板id为: 1. 内容为: 【云通讯】您的验证码是{1},请于{2}分钟内正确输 入。
# mobile = '13303479527'
# datas = ('666777', '5') # 模板中的参数按照位置传递
resp = sdk.sendMessage(tid, phone, datas)
return resp
3.在视图函数中使用
3.1 在verifications/urls.py
中添加路由
urlpatterns = [
path('sms_codes/', views.SmsCodeView.as_view()),
]
3.2 verifications/views.py
中写试图函数
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
from rest_framework.response import Response
import re
import random
from utils.rl_sms import send_message
class SmsCodeView(APIView):
# 1. 所有人可以访问
permission_classes = (AllowAny,)
def post(self, request):
# 1. 获取参数
phone = request.data.get('phone') image_code =
request.data.get('image_code') image_code_uuid =
request.data.get('image_code_uuid')
# 2. 检查参数
if not all([phone, image_code, image_code_uuid]):
return Response({"code": 999, "msg": "参数不全"})
if not re.match(r'^1[3456789]\d{9}$', phone):
return Response({"code": 999, "msg": "手机号码不正确"})
# 3. 检查是否发送
redis_client = get_redis_connection('img_code')
phone_exists = redis_client.get(phone)
if phone_exists:
return Response({"code": 999, "msg": "频繁发送, 请稍后再试"})
redis_image_code = redis_client.get(image_code_uuid) # bytes
if redis_image_code:
# bytes 转成 string
redis_image_code = redis_image_code.decode()
# 比较用户提供的图片内容是否和redis中保存的一致
if image_code.upper() != redis_image_code:
return Response({'code': 999, 'msg': '图片验证码不正确'})
# 4. 发送
code = '%06d' % random.randint(0, 999999) # 随机6位验证码
send_resp = send_message(phone, (code, "5"))
# 5.1 保存code 到 redis中
# redis_client.setex(phone, 60 * 5, code) # phone:code, 5分钟有效期
# 5.2 从redis中删除这个图片验证码, 以防再次被使用
# redis_client.delete(image_code_uuid)
# 5.3 使用 pipeline 批量操作
pl = redis_client.pipeline()
pl.setex(phone, 60 * 5, code)
pl.delete(image_code_uuid)
pl.execute()
pl.execute()
return Response({"code": 0, "msg": "短信发送成功"})
4.vue发送短信逻辑
-
前端函数如下,js方法代码无需更改,前端代码逻辑在
components\common\lab_header.vue
-
只需要修改
components\axios_api\http.js
中调用的后端地址-
// axios.defaults.baseURL = "http://127.0.0.1:8000/" axios.defaults.baseURL = "http://192.168.56.100:8888/"
-
// 获取手机验证码
sendcode() {
// 0. 判断是否发送中
if (this.is_send) {
return
}
this.check_phone()
this.check_imgcode()
if (this.phone_error ||
this.imgCode_error) {
return false
}
// 3、短信发送
// imgCode: '',
// uuid: '',
var data = { phone: this.phone, image_code_uuid: this.uuid, image_code: this.imgCode }
this.is_send = true
send_phone_code_post(data).then((res) =>
{
console.log(res)
if (res.code != 0) {
this.errorMsg = res.msg
return
}
let t = 10
let si = setInterval(() => {
this.msgButtonText = t
t = t - 1
if (t == 0) {
this.is_send = false
this.msgButtonText = '获取手机验证码'
clearInterval(si)
}
}, 1000)
// if (res.data.code == 200) {
// console.log('短信发送成功')
// alert(res.data.message)
// } else {
// alert(res.data.message)
// }
}).catch((err) => {
console.log(err)
})
},
5. django添加检查用户名和手机号数量接口
5.1 在user/urls.py
中添加
urlpatterns = [
path('count/', views.RegCountView.as_view()), # 查询用户名手机
号使用量的视图, /user/count/
]
5.2 在user/views.py
中添加视图函数
# 查询用户数量接口
class RegCountView(APIView):
# 注册时需要验证的用户名和手机号是否使用
# 自定义权限类
permission_classes = (AllowAny,)
def post(self, request):
# 接收参数: 验证的内容type:
username/phone, data: '用户名' 或者 '手机号',
datatype = request.data.get('type')
data = request.data.get('data')
if not all([data, datatype]):
return Response({'code': 999, 'msg': '参数不完整'}) if datatype == 'username':
count =
User.objects.filter(username=data).count()
if datatype == 'phone':
count =
User.objects.filter(phone=data).count()
return Response({'code': 0, 'msg': '查询成功', 'data': {'type': datatype, 'count': count}})
6. 测试接口
- 测试接口URL
http://192.168.56.100:8888/user/count/
7. vue检查用户名是否重复
-
前端函数如下,js方法代码无需更改,前端代码逻辑在
components\common\lab_header.vue
-
只需要修改
components\axios_api\http.js
中调用的后端地址-
// axios.defaults.baseURL = "http://127.0.0.1:8000/" axios.defaults.baseURL = "http://192.168.56.100:8888/"
-
// 检查用户名 是否使用
check_username() {
console.log('判断用户名')
console.log(this.username == '')
var reg = new RegExp(/^[a-zA-Z0-9_-]{3,16}$/); //字符串正则表达式 4到14位(字母,数字,下划线,减号)
if (this.username == '') {
this.username_message = '用户名不能为空'
this.username_error = true
return false
}
if (!reg.test(this.username)) {
this.username_message = '用户名格式不正确'
this.username_error = true
return false
} else {
// 去后端检查用户名使用数量
user_count({ type: 'username', data: this.username }).then((res) => {
console.log(res)
if (res.data.count > 0) {
this.username_message = '用户名已存在'
this.username_error = true
} else {
this.username_message = ''
this.username_error = false
}
})
}
},
8. vue检查手机号是否重复
// 检查手机号是否使用
check_phone() {
console.log('检查手机号')
var reg = new RegExp(/^[1]([3-9])[0-9]{9}$/)
if (this.phone == '') {
this.phone_message = '手机号不能为空'
this.phone_error = true
}
if (!reg.test(this.phone)) {
this.phone_message = '手机号格式不正确'
this.phone_error = true
return false
} else {
// 去后端查用户数量
user_count({ type: 'phone', data: this.phone }).then((res) => {
console.log(res)
if (res.data.count > 0) {
this.phone_message = '手机号已存在'
this.phone_error = true
} else {
this.phone_message = ''
this.phone_error = false
}
})
}
},
9. 完善注册接口
修改user/views.py
中完善视图函数
# 注册接口
class RegisterView(APIView):
"""
用户注册, 权限是: 匿名用户可访问
"""
# 自定义权限类
permission_classes = (AllowAny,)
def post(self, request):
"""
接收用户名,密码,手机号和验证码, 前端校验两遍一致性, 注册成功后返回成功, 然后用户自行登录获取token
1. 用户名
2. 密码
3. 手机号
4. 验证码
:param request:
:return: {'code':0,'msg':'注册成功'}
code: "260361"
password: "123123"
phone: "13303479527"
username: "liangxuepeng"
"""
username = request.data.get('username')
phone = request.data.get('phone')
code = request.data.get('code')
passwrod = request.data.get('password')
if all([username, passwrod, phone, code]):
pass
else:
return Response({'code': 999, 'msg': '参数不全'})
# rand_name = self.randomUsername()
# 验证手机验证码
redis_client = get_redis_connection('verify_code')
code_redis = redis_client.get(phone)
if code_redis:
code_redis = code_redis.decode()
if not code == code_redis:
return Response({'code': 999, 'msg': '手机验证码错误'})
user = User(username=username, phone=phone)
user.set_password(passwrod)
user.save()
return Response({'code': 0, 'msg': '注册成功'})