发送短信验证码的功能开发

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': '注册成功'})
posted @ 2020-10-07 20:11  ihszg  阅读(466)  评论(0编辑  收藏  举报