潭州課堂25班:Ph201805201 django 專案 第十一課 手機號是否存在,簡訊驗證分析 (課堂筆記)
1.分析
請求方法:GET
url定義:/mobiles/(?P<mobile>1[3-9]\d{9})/
請求引數:url路徑引數
引數 | 型別 | 前端是否必須傳 | 描述 |
---|---|---|---|
mobile | 字串 | 是 | 使用者輸入的手機號 |
# 在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("獲取手機簡訊驗證碼過於頻繁")