1. 程式人生 > >潭州課堂25班:Ph201805201 django 專案 第十一課 手機號是否存在,簡訊驗證分析 (課堂筆記)

潭州課堂25班:Ph201805201 django 專案 第十一課 手機號是否存在,簡訊驗證分析 (課堂筆記)

判斷手機號是否註冊功能實現

1.分析

請求方法GET

url定義/mobiles/(?P<mobile>1[3-9]\d{9})/

請求引數:url路徑引數

引數 型別 前端是否必須傳 描述
mobile 字串 使用者輸入的手機號

 

2.後端程式碼實現

# 在verifications目錄下的views.py檔案中定義如下類檢視:

class MobileView(View):
"""
判斷手機號是否存在
"""
def get(self, request, username):
data = {
'mobile': mobile,
'count': Users.objects.filter(mobile=mobile).count()
}
return to_json_data(data=data)


在 urls 檔案中:進行路由匹配:

re_path('mobiles/(?P<mobile>1[3-9]\d{9})/', views.CheckMobileView.as_view(), name='check_mobiles'),

前臺程式碼程式碼:js 檔案:

$(function () {
let $username = $('#user_name'); // 選擇id為user_name的網頁元素,需要定義一個id為user_name
let $img = $(".form-item .captcha-graph-img img"); // 獲取影象標籤
let sImageCodeId = ""; // 定義影象驗證碼ID值
let $mobile = $('#mobile'); // 選擇id為mobile的網頁元素,需要定義一個id為mobile

// 1、影象驗證碼邏輯
generateImageCode(); // 生成影象驗證碼圖片
$img.click(generateImageCode); // 點選圖片驗證碼生成新的圖片驗證碼圖片


// 判斷使用者是否註冊
// 2、使用者名稱驗證邏輯
$username.blur(function () {
fn_check_usrname();
});

// 3、手機號驗證邏輯
// 判斷使用者手機號是否註冊
$mobile.blur(function () {
fn_check_mobile();
});


// 生成一個圖片驗證碼的編號,並設定頁面中圖片驗證碼img標籤的src屬性
function generateImageCode() {
// 1、生成一個圖片驗證碼隨機編號
sImageCodeId = generateUUID();
// 2、拼接請求url /image_codes/<uuid:image_code_id>/
let imageCodeUrl = "/image_codes/" + sImageCodeId + "/";
// 3、修改驗證碼圖片src地址
$img.attr('src', imageCodeUrl)

}

// 生成圖片UUID驗證碼
function generateUUID() {
let d = new Date().getTime();
if (window.performance && typeof window.performance.now === "function") {
d += performance.now(); //use high-precision timer if available
}
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}

// 判斷使用者名稱是否已經註冊
function fn_check_usrname() {
let sUsername = $username.val(); // 獲取使用者名稱字串
if (sUsername === "") {
message.showError('使用者名稱不能為空!');
return
}
// test()方法 判斷字串中是否匹配到正則表示式內容,返回的是boolean值 ( true / false )
if (!(/^\w{5,20}$/).test(sUsername)) {
message.showError('請輸入5-20個字元的使用者名稱');
return
}

// 傳送ajax請求,去後端查詢使用者名稱是否存在
$.ajax({
url: '/usernames/' + sUsername + '/',
type: 'GET',
dataType: 'json',
// data:{'code':300268}
})
.done(function (res) {
if (res.data.count !== 0) {
message.showError(res.data.username + '已註冊,請重新輸入!')
} else {
message.showInfo(res.data.username + '能正常使用!')
}
})
.fail(function () {
message.showError('伺服器超時,請重試!');
});
}

function fn_check_mobile() {
let sMobile = $mobile.val(); // 獲取使用者輸入的手機號碼字串
let SreturnValue = "";
if (sMobile === "") {
message.showError('手機號不能為空!');
return
}
if (!(/^1[345789]\d{9}$/).test(sMobile)) {
message.showError('手機號碼格式不正確,請重新輸入!');
return
}

$.ajax({
url: '/mobiles/' + sMobile + '/',
type: 'GET',
dataType: 'json',
async: false // 把async關掉
})
.done(function (res) {
if (res.data.count !== 0) {
message.showError(res.data.mobile + '已註冊,請重新輸入!')
SreturnValue = ""
} else {
SreturnValue = "success"
}
})
.fail(function () {
message.showError('伺服器超時,請重試!');
SreturnValue = ""
});
return SreturnValue

}

});

 

傳送手機簡訊驗證碼功能實現

1.分析

業務處理流程:

  • 檢查圖片驗證碼是否正確

  • 檢查是否在60s內有傳送記錄

  • 生成簡訊驗證碼

  • 儲存簡訊驗證碼與傳送記錄

  • 傳送簡訊

 

請求方法POST

url定義/sms_codes

請求引數:url路徑引數

引數 型別 前端是否必須傳 描述
mobile 字串 使用者輸入的手機號
image_code_id UUID js生成的圖片uuid號
text 字串 使用者輸入的圖片驗證碼文字

注:由於是post請求,在向後端發起請求時,需要附帶csrf token

 1,建立個類,

2,獲取前臺引數,

3,校驗引數,

4,傳送簡訊驗證碼,

5,儲存簡訊驗證碼

6,返回前臺引數

 

在verifications目錄下的forms.py檔案中定義如下form表單:

# 建立手機號的正則校驗器

from django import forms
from django.core.validators import RegexValidator
from django_redis import get_redis_connection

from users.models import Users

mobile_validator = RegexValidator(r"^1[3-9]\d{9}$", "手機號碼格式不正確")

a
class CheckImgCodeForm(forms.Form):
    """
    check image code
    """
    mobile = forms.CharField(max_length=11, min_length=11, validators=[mobile_validator, ],
                             #  錯誤提示資訊
                             error_messages={"min_length": "手機號長度有誤", "max_length": "手機號長度有誤",
                                             "required": "手機號不能為空"})
    image_code_id = forms.UUIDField(error_messages={"required": "圖片UUID不能為空"})
    text = forms.CharField(max_length=4, min_length=4,
                           error_messages={"min_length": "圖片驗證碼長度有誤", "max_length": "圖片驗證碼長度有誤",
                                           "required": "圖片驗證碼不能為空"})

    # Cleaning and validating fields that depend on each other
    def clean(self):
        cleaned_data = super().clean()
        # 1、
        image_uuid = cleaned_data.get("image_code_id")
        image_text = cleaned_data.get("text")
        mobile_num = cleaned_data.get("mobile")

        # 2、
        if Users.objects.filter(mobile=mobile_num).count():
            raise forms.ValidationError("手機號已註冊,請重新輸入")

        # 確保settings.py檔案中有配置redis CACHE
        # Redis原生指令參考 http://redisdoc.com/index.html
        # Redis python客戶端 方法參考 http://redis-py.readthedocs.io/en/latest/#indices-and-tables
        # 2、
        con_redis = get_redis_connection(alias='verify_codes')
        # 建立儲存到redis中圖片驗證碼的key
        img_key = "img_{}".format(image_uuid).encode('utf-8')

        # 取出圖片驗證碼
        real_image_code_origin = con_redis.get(img_key)
        real_image_code = real_image_code_origin.decode('utf-8') if real_image_code_origin else None
        con_redis.delete(img_key)

        # 驗證手機號
        if (not real_image_code) or (image_text != real_image_code):
            raise forms.ValidationError("圖片驗證失敗")

        # 檢查是否在60s內有傳送記錄
        sms_flag_fmt = "sms_flag_{}".format(mobile_num).encode('utf-8')
        sms_flag = con_redis.get(sms_flag_fmt)
        if sms_flag:
            raise forms.ValidationError("獲取手機簡訊驗證碼過於頻繁")