1. 程式人生 > >Django簡訊驗證碼

Django簡訊驗證碼

Django簡訊驗證碼

在阿里雲中購買簡訊服務https://www.aliyun.com/

將簡訊驗證碼儲存到redis中, 存取速度快,減輕mysql資料庫伺服器壓力。

redis中的鍵可以設定過期時間, 簡訊驗證碼可以設定2分鐘過期時間,過期自動銷燬。

獲取redis連線

# 匯入redis連線方法
from django_redis import get_redis_connection
# 使用預設配置連線到redis
cnn = get_redis_connection('default')
# 使用連線上的方法操作redis
cnn.hset('物件名'
'屬性''值')

使用redis的命令

檢視手冊http://doc.redisfans.com/

封裝兩個方法:

傳送手機簡訊的方法

# 傳送手機驗證碼
def send_phone_code(request):
    """
    :param request:  HttpRequest 請求物件
    :param phone:  手機號碼
    :return: 返回結果
    """
    try:
        # 獲取手機號碼
        phone = request.GET.get('phone')
        # 驗證手機號是否正確
phone_re = re.compile('^1[3-9]\d{9}$') res = re.search(phone_re, phone) if res: # 生成隨機驗證碼 code = "".join([str(random.randint(0, 9)) for _ in range(4)]) print(code) print("===========================") # 儲存到redis中 ,等你驗證的時候使用
r = get_redis_connection('default') r.set(tel, code) # 設定過期時間 redis r.expire(tel, 120) # 傳送簡訊驗證碼 __business_id = uuid.uuid1() # 資訊 params = "{\"code\":\"%s\"}" % code rs = send_sms(__business_id, phone, "模板名稱", "SMS_141905190", params) print(rs.decode('utf-8')) return {'ok': 1, 'code': 200} else: return {'ok': 0, 'code': 500, 'msg': '手機號碼格式錯誤!'} except: return {'ok':0,'code':500,'msg':'簡訊驗證碼傳送失敗'}

傳送的方法

# 傳送簡訊
def send_sms(business_id, phone_numbers, sign_name, template_code, template_param=None):
    # 注意:不要更改
    REGION = "cn-hangzhou"
    PRODUCT_NAME = "Dysmsapi"
    DOMAIN = "dysmsapi.aliyuncs.com"
    # acs_client = AcsClient(const.ACCESS_KEY_ID, const.ACCESS_KEY_SECRET, REGION)
    acs_client = AcsClient(settings.ACCESSKEYID, settings.ACCESSKEYSECRET, REGION)
    region_provider.add_endpoint(PRODUCT_NAME, REGION, DOMAIN)
    smsRequest = SendSmsRequest.SendSmsRequest()
    # 申請的簡訊模板編碼,必填
    smsRequest.set_TemplateCode(template_code)
    # 簡訊模板變數引數
    if template_param is not None:
        smsRequest.set_TemplateParam(template_param)
    # 設定業務請求流水號,必填。
    smsRequest.set_OutId(business_id)
    # 簡訊簽名
    smsRequest.set_SignName(sign_name)
    # 資料提交方式
    # smsRequest.set_method(MT.POST)
    # 資料提交格式
    # smsRequest.set_accept_format(FT.JSON)
    # 簡訊傳送的號碼列表,必填。
    smsRequest.set_PhoneNumbers(phone_numbers)
    # 呼叫簡訊傳送介面,返回json
    smsResponse = acs_client.do_action_with_exception(smsRequest)
    # TODO 業務處理
    return smsResponse  return smsResponse

建立檢視函式並繫結路由

# 簡訊傳送 檢視函式
def sendMsg(request):
    return JsonResponse(send_phone_code(request))
# 8. 路由繫結
urlpatterns = [
    url(r'^sendMsg/$', sendMsg, name='sendMsg'), # 發簡訊
]

ajax 點選按鈕 js 程式碼

{% block footer_js %}
    <script>
        $(function () {
            // 驗證碼按鈕上繫結點選事件
            $(".yzm-hq").on('click', function () {
                // 由於this會在很多匿名函式中使用,先將其儲存在一個變數中
                // 因為其他匿名函式中有自己的this,會和點選事件的this衝突
                var that = this;
                // 獲取手機號碼
                phone = $("input[name='phone']").val();
                // 通過ajax傳送get請求
                $.get('{% url "sp_user:sendMsg" %}', {'phone': phone}, function (data) {
                    //判斷是否請求成功
                    if (data.ok == 1) {
                        // 設定 60 秒後可以重新發送驗證碼
                        var time = 60;
                        // 立馬 將按鈕禁用 防止重複點選提交
                        $(that).attr('disabled', true);
                        // 顏色設定為 灰色
                        $(that).css({'backgroundColor': "gray"});
                        // 將按鈕提示文字改變
                        showMsg(that, time);
                        // 設定週期性執行, 週期性改變顯示文字內容
                        var timer = window.setInterval(function () {
                            // 時間減少
                            --time;
                            // 顯示文字
                            showMsg(that, time);
                            // 判斷是否到期
                            if (time == 0) {
                                // 到期後清除定時器
                                window.clearInterval(timer);
                                // 啟用按鈕
                                $(that).attr('disabled', false);
                                // 改變顏色和文字內容
                                $(that).css({'backgroundColor': "#76bb2a"});
                                $(that).val("獲取驗證碼");
                            }
                        }, 1000)
                    } else {
                        alert(data.msg);
                    }
                })
            });
            //改變按鈕 倒計時顯示內容
            function showMsg(obj, time) {
                var msg = time + "秒後重新發送!";
                $(obj).val(msg);
            }
        })
    </script>
{% endblock %}

在RegisterView註冊檢視中驗證提交的驗證碼核心程式碼

form表單中的核心驗證驗證碼的程式碼

# 驗證碼欄位新增
verify_code = forms.CharField(error_messages={"required": "請填寫驗證"})
# 單獨使用一個方法校驗 驗證碼
def clean_verify_code(self):
    # 驗證驗證碼是否填寫正確
    # 獲取redis中的驗證碼
    r = get_redis_connection()
    tel = self.cleaned_data.get('phone')
    s_verify_code = r.get(tel)
    if not s_verify_code:
        raise forms.ValidationError("驗證碼已經過期")
    # 表單傳入的驗證碼
    verify_code = self.cleaned_data.get('verify_code')
    # sid_verify_code = self.data.get('sid_verify_code')
    if int(verify_code) != int(s_verify_code):
        raise forms.ValidationError("驗證碼輸入有誤")
    return verify_code