短信驗證碼

 

1. 業務處理流程

  1. 檢查圖片驗證碼
  2. 檢查是否在60s內有發送記錄
  3. 生成短信驗證碼
  4. 保存短信驗證碼與發送記錄
  5. 發送短信

2. 後端接口設計:

訪問方式: GET /sms_codes/(?P<mobile>1[3-9]\d{9})/?image_code_id=xxx&text=xxx前端

請求參數: 路徑參數與查詢字符串參數python

參數 類型 是否必須 說明
mobile str 手機號
image_code_id uuid字符串 圖片驗證碼編號
text str 用戶輸入的圖片驗證碼

返回數據: JSONredis

返回值 類型 是否必傳 說明
message str OK,發送成功

視圖原型:後端

# url('^sms_codes/(?P<mobile>1[3-9]\d{9})/$', views.SMSCodeView.as_view()), class SMSCodeView(GenericAPIView): """ 短信驗證碼 傳入參數: mobile, image_code_id, text """ pass 

3. 後端實現

在verifications/serializers.py中定義序列化器,用以校驗dom

class ImageCodeCheckSerializer(serializers.Serializer): """ 圖片驗證碼校驗序列化器 """ image_code_id = serializers.UUIDField() text = serializers.CharField(max_length=4, min_length=4) def validate(self, attrs): """ 校驗 """ image_code_id = attrs['image_code_id'] text = attrs['text'] # 查詢真實圖片驗證碼 redis_conn = get_redis_connection('verify_codes') real_image_code_text = redis_conn.get('img_%s' % image_code_id) if not real_image_code_text: raise serializers.ValidationError('圖片驗證碼無效') # 刪除圖片驗證碼 try: redis_conn.delete('img_%s' % image_code_id) except RedisError as e: logger.error(e) # 比較圖片驗證碼 real_image_code_text = real_image_code_text.decode() if real_image_code_text.lower() != text.lower(): raise serializers.ValidationError('圖片驗證碼錯誤') # 判斷是否在60s內 mobile = self.context['view'].kwargs['mobile'] send_flag = redis_conn.get("send_flag_%s" % mobile) if send_flag: raise serializers.ValidationError('請求次數過於頻繁') return attrs 

在verifications/views.py中定義實現視圖:ui

class SMSCodeView(GenericAPIView): """ 短信驗證碼 """ serializer_class = serializers.ImageCodeCheckSerializer def get(self, request, mobile): """ 建立短信驗證碼 """ # 判斷圖片驗證碼, 判斷是否在60s內 serializer = self.get_serializer(data=request.query_params) serializer.is_valid(raise_exception=True) # 生成短信驗證碼 sms_code = "%06d" % random.randint(0, 999999) # 保存短信驗證碼與發送記錄 redis_conn = get_redis_connection('verify_codes') pl = redis_conn.pipeline() pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) pl.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) pl.execute() # 發送短信驗證碼 sms_code_expires = str(constants.SMS_CODE_REDIS_EXPIRES // 60) ccp = CCP() ccp.send_template_sms(mobile, [code, expires], SMS_CODE_TEMP_ID) return Response({"message": "OK"}) 
相關文章
相關標籤/搜索