准備:
1.容聯雲通信注冊賬號並下載設置
2.將yuntongxun文件夾復制到項目目錄下
短信驗證碼業務分析: 需要使用redis數據庫 配置文件里添加如下設置
CACHES = { "default": { # 默認的緩存配置 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/0", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, # 我的需求是希望將session存儲在redis的1號庫 "session": { # session后端 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, "verify_code": { # 驗證碼 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, }
短信驗證碼后端接口設計:
1.請求方式 選項 方案 請求方法 GET 請求地址 /sms_codes/(?P<mobile>1[3-9]\d{9})/ 請求參數:路徑參數和查詢字符串傳參 其中:mobile 是用路徑傳遞參數的, image_code 和 image_code_id 是用查詢字符串傳遞的參數. 2.參數名 類型 是否必傳 說明 mobile string 是 手機號 image_code string 是 圖形驗證碼 image_code_id string 是 唯一編號 3.響應結果:JSON 字段 說明 code 狀態碼 errmsg 錯誤信息
短信驗證碼實現 在視圖集文件里添加代碼
class SMSCodeView(View): def get(self, reqeust, mobile): # 避免頻繁發送短信驗證碼 redis_conn = get_redis_connection('verify_code') send_flag = redis_conn.get('send_flag_%s' % mobile) if send_flag: return http.JsonResponse({'code': 400, 'errmsg': '發送短信過於頻繁'}) image_code_client = reqeust.GET.get('image_code') uuid = reqeust.GET.get('image_code_id') if not all([image_code_client, uuid]): return http.JsonResponse({'code': 400, 'errmsg': '缺少必傳參數'}) image_code_server = redis_conn.get('img_%s' % uuid) if image_code_server is None: return http.JsonResponse({'code': 400, 'errmsg': '圖形驗證碼失效'}) try: redis_conn.delete('img_%s' % uuid) except Exception as e: logger.error(e) image_code_server = image_code_server.decode() if image_code_client.lower() != image_code_server.lower(): return http.JsonResponse({'code': 400, 'errmsg': '輸入圖形驗證碼有誤'}) sms_code = '%06d' % random.randint(0, 999999) logger.info(sms_code) # 創建管道對象: pl = redis_conn.pipeline() # redis_conn.setex('sms_%s' % mobile, 300, sms_code) pl.setex('sms_%s' % mobile, 300, sms_code) # redis_conn.setex('send_flag_%s' % mobile, 60, 1) pl.setex('send_flag_%s' % mobile, 60, 1) # 執行管道: pl.execute() CCP().send_template_sms(mobile, [sms_code, 5], 1) return http.JsonResponse({'code': 0, 'errmsg': '發送短信成功'})
配置短信驗證碼的url
urlpatterns = [ re_path(r"^sms_codes/(?P<mobile>1[3-9]\d{9})/$", views.SMSCodeView.as_view()), ]
短信驗證碼后端常見優化:
1. 如何避免頻繁發送短信驗證碼: 在后端也要限制用戶請求短信驗證碼的頻率. 60秒內只允許一次請求短信驗證碼. 在 Redis 數據庫中緩存一個數值,有效期設置為60秒. 2. Redis服務端問題: 如果Redis服務端需要同時處理多個請求,加上網絡延遲, 那么服務端利用率不高,效率降低。 解決方案:pipeline 1. 創建redis請求管道 2. 將操作redis的多個命令請求添加到管道隊列里 3. 執行命令 3.發送短信是耗時操作,如果短信被阻塞,用戶響應會延遲,影響用戶界面倒計時延遲 """ CCP().send_template_sms(mobile, [sms_code, 5], 1) return http.JsonResponse({'code': 0, 'errmsg': '發送短信成功'}) """ 解決方案:異步方案redis 和 Celey 異步發送短信 將發送短信業務和響應分開執行,將發送短信 從主業務中 解耦出來