目錄
1.簡訊sdk接入
1.準備工作
1.下載雲通訊相關的檔案 https://github.com/cloopen/python-sms-sdk
2.在lyapi目錄下建立一個lib資料夾,將ronglian_sms_sdk資料夾放入lib資料夾中
3.資料夾下的目錄結構如圖所示
4.登入
ACCOUNT SID:8a216da863f8e6c20164139687e80c1b
AUTH TOKEN : 6dd01b2b60104b3dbc88b2b74158bac6
AppID(預設):8aaf0708697b6beb01699f4442e3177c
2.使用容聯雲通訊傳送簡訊
sms.py
from django.conf import settings from .SmsSDK import SmsSDK import json accId = settings.SMS_INFO.get('ACCID') accToken = settings.SMS_INFO.get('ACCTOKEN') appId = settings.SMS_INFO.get('APPID') def send_message(tid, mobile, datas): sdk = SmsSDK(accId, accToken, appId) resp = sdk.sendMessage(tid, mobile, datas) resp = json.loads(resp) print(resp) return resp.get('statusCode') == '000000'
dev.py
SMS_INFO = { 'ACCID':'8a216da8754a45d5017563ac8e8406ff', 'ACCTOKEN':'a2054f169cbf42c8b9ef2984419079da', 'APPID':'8a216da8754a45d5017563ac8f910705', }
views.py
# views.py '''todo 傳送驗證碼''' import logging logger = logging.getLogger('django') from lyapi.libs.ronglian_sms_sdk.sms import send_message from django.conf import settings class GetSMSCodeView(APIView): def get(): ...... # 傳送驗證碼 ret = send_message(settings.SMS_INFO.get('TID'),phone,(sms_code,constants.SMS_CODE_EXPIRE_TIME)) if not ret: logger.error('{}手機號簡訊傳送失敗'.format(phone)) return Response({'msg':'簡訊傳送失敗 ,請聯絡管理員!!'},status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'msg': 'ok'})
3.drf後端介面測試
訪問users/sms_code/13015409856,可得到msg:ok 並且手機會接受到驗證碼資訊
2.前端點選獲取驗證碼效果
1.在register.vue中給獲取驗證碼按鈕繫結個點選事件
<!-- html --> <div> <input v-model = "sms" type="text" placeholder="輸入驗證碼" class="user" style="width: 62%"> <button style="width: 34%;height: 41px;" @click="getSmsCode">{{ btn_msg }}</button> </div>
// js <script> export default { name: 'Register', data(){ return { ...... interval_time:60, // 倒數計時時間 btn_msg:'點選獲取驗證碼', // 按鈕上面的資訊 flag:false // 判斷定時器是否已經開啟 } }, created(){ }, methods:{ ...... getSmsCode(){ this.$axios.get(`${this.$settings.Host}/users/sms_code/${this.mobile}/`) .then(()=>{ // 計時器 this.flag = setInterval(()=>{ if(this.interval_time > 0){ this.interval_time--; this.btn_msg=`${this.interval_time}秒後重新獲取`; }else{ this.interval_time=60; this.btn_msg='點選傳送驗證碼'; clearInterval(this.flag); this.flag=false; } },1000) }) .catch(()=>{ }) } }, }; </script>
這個時候 我們在註冊頁面點選獲取驗證碼按鈕 手機上就可以收到簡訊了
2.效果:按鈕變為不可點選
獲取驗證碼時,按鈕顯示倒數計時,並且倒數計時時按鈕不可點選
<!-- html --> <div> <input v-model = "sms" type="text" placeholder="輸入驗證碼" class="user" style="width: 62%"> <button style="width: 34%;height: 41px;" @click="getSmsCode" :disabled="this.flag">{{ btn_msg }}</button> </div>
// js <script> export default { name: 'Register', data(){ return { validateResult:false, interval_time:60, btn_msg:'點選獲取驗證碼', flag:false, } }, created(){ }, methods:{ ...... getSmsCode(){ this.$axios.get(`${this.$settings.Host}/users/sms_code/${this.mobile}/`) .then((res)=>{ this.flag = setInterval(()=>{ if(this.interval_time > 0){ this.interval_time--; this.btn_msg=`${this.interval_time}秒後重新獲取`; this.disabled = true; // 將按鈕設定為不可點選 }else{ this.interval_time=60; this.btn_msg='點選傳送驗證碼'; clearInterval(this.flag); this.flag=false; this.disabled = false // 將按鈕設定為可點選 } },1000) }) .catch((error)=>{ })
3.效果:前端顯示:60s已經發過了,別瞎搞
register.vue
// register.vue getSmsCode(){ this.$axios.get(`${this.$settings.Host}/users/sms_code/${this.mobile}/`) ...... .catch((error)=>{ this.$message.error(error.response.data.msg); // 列印錯誤資訊 })
3.註冊後端介面實現
1.後端序列化器對驗證碼的校驗
serializers.py
# serializers.py from rest_framework import serializers from django_redis import get_redis_connection ...... # todo 校驗驗證碼 def validate(self, attrs): ...... conn = get_redis_connection('sms_code') # 獲取redis所存放驗證碼的那個庫物件 ret = conn.get('mobile_%s' % (phone_number)) # 獲取到手機號對應的驗證碼 if not ret: # 如果驗證碼不存在 raise serializers.ValidationError('驗證碼已失效') if ret.decode() != sms: # 如果驗證碼不對 raise serializers.ValidationError('驗證碼輸入錯誤') return attrs ......
2.當使用者註冊成功後,後端應該返回給前端一個真實的token值
serializers.py
# serializers.py def create(self, validated_data): ...... # 通過jwt生成一個真實的token值返回給前端 payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) user.token = token return user
提交手機號/密碼/確認密碼/驗證碼 看是否能拿到後端傳給我們的id phone token值
4.註冊-前端
如果校驗通過,應該將後端發過來的id username token存到sessionStorage中 並跳轉到首頁介面
如果校驗失敗,應該在前端展示對應的錯誤資訊
register.vue
<script> export default { name: 'Register', data(){ return { sms:"", mobile:"", password:"", r_password:"", validateResult:false, interval_time:60, // /倒數計時時間 btn_msg:'點選獲取驗證碼', flag:false, // 判斷定時是否已經開啟 } }, created(){ }, methods:{ ...... registerHandler(){ this.$axios.post(`${this.$settings.Host}/users/register/`,{ sms:this.sms, phone:this.mobile, password:this.password, r_password:this.r_password, }).then((res)=>{
// 註冊成功 將id token username儲存到前端 並跳轉到首頁 sessionStorage.token = res.data.token; sessionStorage.username = res.data.username; sessionStorage.id = res.data.id; this.$router.push('/') // 跳轉到首頁 }).catch((error)=>{
// 註冊失敗 列印錯誤資訊 console.log(error.response); }) }, getSmsCode(){ this.$axios.get(`${this.$settings.Host}/users/sms_code/${this.mobile}/`) .then((res)=>{ this.flag = setInterval(()=>{ if(this.interval_time > 0){ this.interval_time--; this.btn_msg=`${this.interval_time}秒後重新獲取`; this.disabled = true; // 點選了獲取驗證碼之後 按鈕變為不可點選 }else{ //倒數計時停止 允許使用者傳送簡訊 this.interval_time=60; this.btn_msg='點選傳送驗證碼'; clearInterval(this.flag); this.flag=false; this.disabled = false } },1000) }) .catch((error)=>{ this.$message.error(error.response.data.msg); }) } }, }; </script>
5.Celery
1.Celery的簡單使用
文件:http://docs.jinkan.org/docs/celery/getting-started/index.html
Celery的特點是:
-
簡單,易於使用和維護,有豐富的文件。
-
高效,單個celery程式每分鐘可以處理數百萬個任務。
-
靈活,celery中幾乎每個部分都可以自定義擴充套件。
2.Celery的架構圖
3.Celery的使用
......以後有時間再補上吧!
6.Celery完成簡訊傳送功能
在最外層lyapi目錄建立mycelery包
檔案目錄結構
# 檔案結構目錄 lyapi/ ├── mycelery/ ├── config.py # 配置檔案 ├── __init__.py ├── main.py # 主程式 └── sms/ └── tasks.py # 任務的檔案,名稱必須是這個!!!
main.py
# main.py from celery import Celery import os os.environ.setdefault('DJANGO_SETTINGS_MODULE','lyapi.settings.dev') import django django.setup() app = Celery() app.config_from_object('mycelery.config') app.autodiscover_tasks(['mycelery.sms',])
config.py
# config.py # 任務佇列的連結地址(變數名必須叫這個) broker_url = 'redis://127.0.0.1:6379/14' # 結果佇列的連結地址(變數名必須叫這個) result_backend = 'redis://127.0.0.1:6379/15'
tasks.py
# tasks.py from mycelery.main import app from lyapi.libs.ronglian_sms_sdk.sms import send_message from django.conf import settings from lyapi.settings import constants import logging logger = logging.getLogger('django') @app.task(name='smsCode') def sms_codes(phone,sms_code): ret2 = send_message(settings.SMS_INFO.get('TID'), phone, (sms_code, constants.SMS_CODE_EXPIRE_TIME // 60)) if not ret2: logger.error('{}手機號簡訊傳送失敗'.format(phone)) return '簡訊傳送成功啦'
views.py
# views.py # 傳送驗證碼 from mycelery.sms.tasks import sms_code sms_code.delay(phone,sms_code) return Response({'msg':'ok'})