本篇主要實現flask應用的短信驗證碼的邏輯實現,其用到的第三方應用為雲通信,其也是通過前端更加需求發送請求,后端接收到請求完成相關業務邏輯。
一、前端業務邏輯實現
其HTML代碼如下:
<div class="form_group"> <input type="text" name="smscode" id="smscode" class="code_pwd"> <div class="input_tip">手機驗證碼</div> <a href="javascript:;" class="get_code" onclick="sendSMSCode()">點擊獲取驗證碼</a> <div id="register-sms-code-err" class="error_tip">驗證碼不能為空</div> </div>
作為前端人員,需要做的是:
- 當用戶點擊獲取驗證碼時,對用戶的填寫的信息做第一步校驗,並且獲取參數(用戶手機號、圖片驗證碼內容、以及圖片驗證碼ID)。
- 在拿到參數之后,向后端發送請求。
- 若請求成功,並且后端完成短信驗證碼的功能時,設置計時器,得到用戶填寫短信驗證碼。
// 發送短信驗證碼 function sendSMSCode() { // 校驗參數,保證輸入框有數據填寫 $(".get_code").removeAttr("onclick"); var mobile = $("#register_mobile").val(); if (!mobile) { $("#register-mobile-err").html("請填寫正確的手機號!"); $("#register-mobile-err").show(); $(".get_code").attr("onclick", "sendSMSCode();"); return; } var imageCode = $("#imagecode").val(); if (!imageCode) { $("#image-code-err").html("請填寫驗證碼!"); $("#image-code-err").show(); $(".get_code").attr("onclick", "sendSMSCode();"); return; } // 發送短信驗證碼 var params = { "mobile": mobile, "image_code": imageCode, "image_code_id": imageCodeId } $.ajax({ url: "/passport/sms_code", type: "post", data: JSON.stringify(params), headers: { "X-CSRFToken": getCookie("csrf_token") }, contentType:"application/json", success: function (resp) { if (resp.errno == "0"){ var num = 60; var t = setInterval(function () { if (num == 1){ clearInterval(t); $(".get_code").html("獲取驗證碼"); $(".get_code").attr("onclick", "sendSMSCode();") }else{ num -= 1; $(".get_code").html(num + "秒") } }, 1000) }else{ $("#register-sms-code-err").html(resp.errmsg); $("#register-sms-code-err").show(); $(".get_code").attr("onclick", "sendSMSCode();") if (resp.errno == "4004") { generateImageCode() } } } }) }
通常會有一個接口文檔,后端需要根據需求判斷需要哪些參數,上例中:
- 手機號 ----(利用手機號通過第三方平台發送短信)
- 圖片驗證碼內容 ----(做校驗,若圖片驗證碼錯誤自然不能發送短信)
- 圖片驗證碼ID ----(后端需要通過該ID從redis中獲取整數的圖片驗證碼文本信息。)
二、后端業務邏輯實現
對於后端而言,還是以下四個步驟:
獲取參數、校驗參數、業務邏輯、返回響應。
我們需要實現的是:
一、對參數校驗 ,校驗手機號的規則是否正確、圖片驗證碼是否與redis中真實驗證碼是否一致、該用戶是否已經注冊等
二、若校驗均通過,需要利用第三方平台發送驗證碼,並將該短信驗證碼保存到redis中,方便用戶點擊注冊的時候校驗。
@passport_blu.route("/sms_code", methods=["POST"]) def send_sms_code(): json_data = request.json mobile = json_data.get("mobile") image_code = json_data.get("image_code") image_code_id = json_data.get("image_code_id") if not all([mobile, image_code, image_code_id]): return jsonify(errno=RET.PARAMERR, errmsg="參數不全") if not re.match("^1[3578][0-9]{9}$", mobile): return jsonify(errno=RET.DATAERR, errmsg="手機號不正確") try: real_image_code = redis_store.get("ImageCode_" + image_code_id) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="數據庫查詢錯誤") if not real_image_code: return jsonify(errno=RET.DBERR,errmsg="驗證碼已經過期") if real_image_code.lower() != image_code.lower(): return jsonify(errno=RET.DATAERR,errmsg="驗證碼輸入錯誤") # num1 = int(real_image_code[:1]) # num2 = int(real_image_code[2:3]) # num = num1 + num2 # if num != int(image_code): # return jsonify(errno=RET.DATAERR, errmsg="驗證碼輸入錯誤") try: user = User.query.filter_by(mobile=mobile).first() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="數據庫查詢錯誤") if user: return jsonify(errno=RET.DATAEXIST,errmsg="該手機號已經被注冊") # 后端自己生成驗證碼 result = random.randint(0, 999999) sms_code = "%06d" % result print("短信驗證碼是:{}".format(sms_code)) # 屌用第三方去發送短信 # result = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES / 60], "1") # if result != 0: # return jsonify(errno=RET.THIRDERR, errmsg="發送短信失敗") try: redis_store.set("SMS_" + mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES) except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="手機驗證碼保存失敗") return jsonify(errno=RET.OK, errmsg="發送成功")
關於第三方平台,可以參考:
關於雲通訊的使用接口,通過該官網的相關文檔去獲取,也可以找度娘,這里便不再復述了。