Python高階應用(3)—— 為你的專案新增驗證碼
驗證碼
驗證碼的作用:
驗證碼在現在來說,是很常見的東西,可以一定程度的保護網站,比如防止網路爬蟲惡意爬取網站資料啊,減少低階的攻擊啊什麼的。但是高階點的騷操作還是不太好防範,所以現在的驗證碼平臺也在升級強化,為了把人和機器嚴格分開。但是這東西,永遠都是看哪一方技術高低的,誰的技術高階,誰就能幹倒另一方了。詳細的就不說了,總而言之,驗證碼可以說是目前所有的面向使用者的平臺都會用到的,所以這項技能必須得會啊。當然不是自己寫一個驗證碼平臺
如下:
常用的驗證碼平臺:
騰訊雲和阿里雲分別都有自己的驗證碼,然後就極驗,還有一些其他的我叫不上名的, 本教程按極驗的官方文件gt3作為案例解析 極驗官網
就這部落格園的驗證碼好像也是用的極驗,小米官網貌似也用的極驗,我感覺極驗挺好的,所以採用他們的
前提:
環境:後端:Python3的django2
安裝:
1.使用官方教程安裝:
按照極驗的 官方文件 來,下載sdk包,解壓得:
然後進入解壓的目錄,使用python setup.py install安裝,但是會報如下錯誤:
這是一個坑,官方文件並沒有做註明 ,開啟setup檔案:
看到了吧,Python中根本沒有utf8的編碼,改成【utf-8】即可,儲存,重新使用命令安裝:
最後提示安裝完成:
由極驗的官方文件可知,極驗支援Python的django ,flask,Tornado 三個框架,這裡我使用django簡單建立一個示例看是否安裝成功,專案名為gtdemo,app名為gtapp:
按照官方文件,直接匯入用使用,但會報錯,根本找不到包:
但是檢視安裝的包確實存在的:
這又是一個坑 ,此時需要這樣,找到剛才那個解壓目錄下的這了:
將geetest.py檔案複製到專案的目錄裡,我這建立了一個utils資料夾,放到此資料夾裡:
同樣的,記得改這裡的編碼:
然後再使用導包命令並執行測試:
沒報錯,這才是完事兒了。
還有就是此時用的geetest檔案並不是安裝包根目錄的geetest.py檔案,這兩個檔案雖然名字一樣,但是是完全不同的,根目錄那個檔案內容,它只是輔助的安裝檔案
此時我們用到的檔案,全部程式碼就不展示了,看我勾選的部分,就是我們準備匯入的模組:
所以這個檔案才是對的
2.使用pip安裝
由於我電腦裝了Python2和3,3剛才是按官方文件手動安裝的且已經安裝了,所以這裡在Python2下用pip安裝:
注:這裡安裝之後能不能直接用要自己去試驗,我的是可以導包,但是具體開發沒有測試,有時間的朋友可以自己測試,我感覺這樣安裝更方便,但有沒有問題就不好說了
還要一個坑 ,如果執行django跑不起來,提示要social_django:
需要安裝這個模組 social-auth-app-django 才行
這時會安裝一大堆東西,安裝完就可以用了
註冊賬號
用別人的東西肯定要有一個賬號才行,去極驗官網註冊一個賬號,極驗的賬號分了個人和公司,按情況來定,我這注冊的是個人號,然後完成後面的操作
註冊完賬號之後登陸極驗的後臺,這些步驟不用展示了,電腦常識就不囉嗦了,登陸之後選行為驗證:
新增一個驗證:
根據情況來填:
部署:
部署服務端
點這裡的指引也可以去官方文件
現在點左邊的管理設定,拿到id和key,這是建立驗證時自動生成的,這兩個引數在程式碼部署會用到
現在終於開始程式碼編寫了,後續步驟按照官方文件沒什麼大的坑了,可以跟著官方文件走了,當然你也可以接著看我的教程,主要就根據實際情況來規劃程式碼怎麼編寫了
部署客戶端:
官方文件裡有相關的引數配置: 點我檢視
具體就自己研究了
下面給一個例項
示例使用
建立一個django專案
當然在下載geetest時,解壓目錄裡其實有模板,可以直接用那個,當然你也可以自定義,我這就直接用極驗官方給的模板
但是注意,官方給的是django1的,如果你的django是1那麼直接可以用,如果你的跟我一樣是django2,那必須做如下修改才行,我給的都是修改過後的,修改之前直接看給的模板:
url:
view:
配置檔案裡其他不用改,新增這個TEMPLATES引數:
程式碼:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] View Code
把根目錄的static檔案改成templates:
啟動專案:
訪問/home:
點選提交又報錯了:
這裡又有一個坑 ,沒用過django1和Django2的朋友可能在這裡就迷糊了,這裡說的意思是WSGIRequest物件沒有session屬性,我開啟wsgi發現根本沒啥可改的,經查,還是配置檔案的問題, 把MIDDLEWARE_CLASS(這是django1的寫法)改成MIDDLEWARE即可
然後下面這個中介軟體也要註釋掉,不然一樣報錯:
調整後測試
改好重啟,訪問/home頁面,點選提交,終於有了我們想要的驗證了:
極驗提供的驗證碼,下面還有兩個:
測試了幾次之後沒有問題
這幾個元件就是極驗官方提供的模板,index.html檔案裡的:
index.html全部程式碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>gt-python-django-demo</title> <style> body { margin: 50px 0; text-align: center; } .inp { border: 1px solid gray; padding: 0 10px; width: 200px; height: 30px; font-size: 18px; } .btn { border: 1px solid gray; width: 100px; height: 30px; font-size: 18px; cursor: pointer; } #embed-captcha { width: 300px; margin: 0 auto; } .show { display: block; } .hide { display: none; } #notice { color: red; } /* 以下遮罩層為demo.使用者可自行設計實現 */ #mask { display: none; position: fixed; text-align: center; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); overflow: auto; } /* 可自行設計實現captcha的位置大小 */ .popup-mobile { position: relative; } #popup-captcha-mobile { position: fixed; display: none; left: 50%; top: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); z-index: 9999; } </style> </head> <body> <h1>極驗驗證SDKDemo</h1> <br><br> <hr> <br><br> <!-- 為使用方便,直接使用jquery.js庫,如您程式碼中不需要,可以去掉 --> <script src="http://code.jquery.com/jquery-1.12.3.min.js"></script> <!-- 引入封裝了failback的介面--initGeetest --> <script src="http://static.geetest.com/static/tools/gt.js"></script> <!-- 若是https,使用以下介面 --> <!-- <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script> --> <!-- <script src="https://static.geetest.com/static/tools/gt.js"></script> --> <div class="popup"> <h2>彈出式Demo,使用ajax形式提交二次驗證碼所需的驗證結果值</h2> <br> <p> <labe>使用者名稱:</labe> <input id="username1" class="inp" type="text" value="極驗驗證"> </p> <br> <p> <label>密碼:</label> <input id="password1" class="inp" type="password" value="123456"> </p> <br> <input class="btn" id="popup-submit" type="submit" value="提交"> <div id="popup-captcha"></div> </div> <script> var handlerPopup = function (captchaObj) { // 成功的回撥 captchaObj.onSuccess(function () { var validate = captchaObj.getValidate(); $.ajax({ url: "/pc-geetest/ajax_validate", // 進行二次驗證 type: "post", dataType: "json", data: { username: $('#username1').val(), password: $('#password1').val(), geetest_challenge: validate.geetest_challenge, geetest_validate: validate.geetest_validate, geetest_seccode: validate.geetest_seccode }, success: function (data) { if (data && (data.status === "success")) { $(document.body).html('<h1>登入成功</h1>'); } else { $(document.body).html('<h1>登入失敗</h1>'); } } }); }); $("#popup-submit").click(function () { captchaObj.show(); }); // 將驗證碼加到id為captcha的元素裡 captchaObj.appendTo("#popup-captcha"); // 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html }; // 驗證開始需要向網站主後臺獲取id,challenge,success(是否啟用failback) $.ajax({ url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加隨機數防止快取 type: "get", dataType: "json", success: function (data) { // 使用initGeetest介面 // 引數1:配置引數 // 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件 initGeetest({ gt: data.gt, challenge: data.challenge, product: "popup", // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效 offline: !data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注 // 更多配置引數請參見:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handlerPopup); } }); </script> <br><br> <hr> <br><br> <form class="popup" action="/pc-geetest/validate" method="post"> <h2>嵌入式Demo,使用表單形式提交二次驗證所需的驗證結果值</h2> <br> <p> <label for="username2">使用者名稱:</label> <input class="inp" id="username2" type="text" value="極驗驗證"> </p> <br> <p> <label for="password2">密碼:</label> <input class="inp" id="password2" type="password" value="123456"> </p> <div id="embed-captcha"></div> <p id="wait" class="show">正在載入驗證碼......</p> <p id="notice" class="hide">請先拖動驗證碼到相應位置</p> <br> <input class="btn" id="embed-submit" type="submit" value="提交"> </form> <script> var handlerEmbed = function (captchaObj) { $("#embed-submit").click(function (e) { var validate = captchaObj.getValidate(); if (!validate) { $("#notice")[0].className = "show"; setTimeout(function () { $("#notice")[0].className = "hide"; }, 2000); e.preventDefault(); } }); // 將驗證碼加到id為captcha的元素裡,同時會有三個input的值:geetest_challenge, geetest_validate, geetest_seccode captchaObj.appendTo("#embed-captcha"); captchaObj.onReady(function () { $("#wait")[0].className = "hide"; }); // 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html }; $.ajax({ // 獲取id,challenge,success(是否啟用failback) url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加隨機數防止快取 type: "get", dataType: "json", success: function (data) { // 使用initGeetest介面 // 引數1:配置引數 // 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件 initGeetest({ gt: data.gt, challenge: data.challenge, product: "embed", // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效 offline: !data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注 // 更多配置引數請參見:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handlerEmbed); } }); </script> <br><br> <hr> <br><br> <div class="popup-mobile"> <h2>移動端手動實現彈出式Demo</h2> <br> <p> <labe for="username3">使用者名稱:</labe> <input id="username3" class="inp" type="text" value="極驗驗證"> </p> <br> <p> <label for="password3">密碼:</label> <input id="password3" class="inp" type="password" value="123456"> </p> <br> <input class="btn" id="popup-submit-mobile" type="submit" value="提交"> <div id="mask"></div> <div id="popup-captcha-mobile"></div> </div> <script> $("#mask").click(function () { $("#mask, #popup-captcha-mobile").hide(); }); $("#popup-submit-mobile").click(function () { $("#mask, #popup-captcha-mobile").show(); }); var handlerPopupMobile = function (captchaObj) { // 將驗證碼加到id為captcha的元素裡 captchaObj.appendTo("#popup-captcha-mobile"); //拖動驗證成功後兩秒(可自行設定時間)自動發生跳轉等行為 captchaObj.onSuccess(function () { var validate = captchaObj.getValidate(); $.ajax({ url: "/mobile-geetest/ajax_validate", // 進行二次驗證 type: "post", dataType: "json", data: { // 二次驗證所需的三個值 username: $('#username3').val(), password: $('#password3').val(), geetest_challenge: validate.geetest_challenge, geetest_validate: validate.geetest_validate, geetest_seccode: validate.geetest_seccode }, success: function (data) { if (data && (data.status === "success")) { $(document.body).html('<h1>登入成功</h1>'); } else { $(document.body).html('<h1>登入失敗</h1>'); } } }); }); // 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html }; $.ajax({ // 獲取id,challenge,success(是否啟用failback) url: "/mobile-geetest/register?t=" + (new Date()).getTime(), // 加隨機數防止快取 type: "get", dataType: "json", success: function (data) { // 使用initGeetest介面 // 引數1:配置引數 // 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件 initGeetest({ gt: data.gt, challenge: data.challenge, offline: !data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注 // 更多配置引數請參見:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handlerPopupMobile); } }); </script> </body> </html> index.html
官方文件裡還有很多驗證元件: 點我檢視
感興趣自己去研究了,實際開發的話,就根據自己的情況稍微改改就行了
實際案例:
本次選用的驗證元件時最常用的先滑動認證,再提交表單的:
做一個簡單的登入驗證平臺,但是不完全用極驗官方的,業務程式碼自己做,畢竟這東西要拿到我們實際開發中,不可能只用用官方給的幾個小demo就完事兒了,開發環境是Python的django2:
建立一個django專案:
然後配置:
url,注意關於兩個極驗的url都指向的是一個檢視類:
view:
html:
標籤元素部分:
js部分:
注意, 這裡還有一個坑 ,瑪德,在這耗了有點久,因為geetest呼叫了request.session,所以,使用django預設的資料庫表django_session,必須要先遷移資料庫,再啟動專案訪問,不然報如下錯:
django.db.utils.OperationalError: no such table: django_session
最後啟動訪問:
點選驗證:
驗證成功的,後面的結果就不展示了
詳細的程式碼,其實都沒改多少,就只是把自己的業務邏輯加上去了,其他的都是直接用極驗官方的
from django.contrib import admin from django.urls import re_path, path from generic.views import AuthView from generic.views import GtView urlpatterns = [ path('admin/', admin.site.urls), path('auth/', AuthView.as_view()), re_path(r'^pc-geetest/register', GtView.as_view()), re_path(r'^pc-geetest/validate$', GtView.as_view()), ] url
# coding:utf-8 from django.shortcuts import render from django.http import HttpResponse from django.views import View from utils.geetest import GeetestLib # 這個id和key是官方的demo裡的,用於展示測試,最好還是註冊一個好點,詳細步驟看上面的教程 pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c" pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4" class AuthView(View): def get(self, request): return render(request, "index.html") class GtView(View): def get(self, request): user_id = 'test' gt = GeetestLib(pc_geetest_id, pc_geetest_key) status = gt.pre_process(user_id) request.session[gt.GT_STATUS_SESSION_KEY] = status request.session["user_id"] = user_id response_str = gt.get_response_str() return HttpResponse(response_str) def post(self, request): if request.method == "POST": gt = GeetestLib(pc_geetest_id, pc_geetest_key) challenge = request.POST.get(gt.FN_CHALLENGE, '') validate = request.POST.get(gt.FN_VALIDATE, '') seccode = request.POST.get(gt.FN_SECCODE, '') status = request.session[gt.GT_STATUS_SESSION_KEY] user_id = request.session["user_id"] if status: result = gt.success_validate(challenge, validate, seccode, user_id) else: result = gt.failback_validate(challenge, validate, seccode) result = "<html><body><h1>登入成功</h1></body></html>" if result else "<html><body><h1>登入失敗</h1></body></html>" return HttpResponse(result) return HttpResponse("error") views
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>gt-python-django-demo</title> <style> body { margin: 50px 0; text-align: center; } .inp { border: 1px solid gray; padding: 0 10px; width: 200px; height: 30px; font-size: 18px; } .btn { border: 1px solid gray; width: 100px; height: 30px; font-size: 18px; cursor: pointer; } #embed-captcha { width: 300px; margin: 0 auto; } .show { display: block; } .hide { display: none; } #notice { color: red; } </style> </head> <body> <h1>請登入</h1> <br><br> <!-- 為使用方便,直接使用jquery.js庫,如您程式碼中不需要,可以去掉 --> <script src="http://code.jquery.com/jquery-1.12.3.min.js"></script> <!-- 引入封裝了failback的介面--initGeetest --> <script src="http://static.geetest.com/static/tools/gt.js"></script> <form class="popup" action="/pc-geetest/validate" method="post"> <p> <label for="username2">使用者名稱:</label> <input class="inp" id="username2" type="text" value="極驗驗證"> </p> <br> <p> <label for="password2">密碼:</label> <input class="inp" id="password2" type="password" value="123456"> </p> <div id="embed-captcha"></div> <p id="wait" class="show">正在載入驗證碼......</p> <p id="notice" class="hide">請先拖動驗證碼到相應位置</p> <br> <input class="btn" id="embed-submit" type="submit" value="提交"> </form> <script> var handlerEmbed = function (captchaObj) { $("#embed-submit").click(function (e) { var validate = captchaObj.getValidate(); if (!validate) { $("#notice")[0].className = "show"; setTimeout(function () { $("#notice")[0].className = "hide"; }, 2000); e.preventDefault(); } }); // 將驗證碼加到id為captcha的元素裡,同時會有三個input的值:geetest_challenge, geetest_validate, geetest_seccode captchaObj.appendTo("#embed-captcha"); captchaObj.onReady(function () { $("#wait")[0].className = "hide"; }); // 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html }; $.ajax({ // 獲取id,challenge,success(是否啟用failback) url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加隨機數防止快取 type: "get", dataType: "json", success: function (data) { // 使用initGeetest介面 // 引數1:配置引數 // 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件 initGeetest({ gt: data.gt, challenge: data.challenge, product: "embed", // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效 offline: !data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注 // 更多配置引數請參見:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handlerEmbed); } }); </script> </body> </html> html模板檔案
總結:
- 1.根據官方文件的步驟來,然後遇到像我這樣的問題就可以試試我的解決方法,還不行自己多研究
- 2.多看官方文件,感覺還是挺簡單的
- 3.注意我提到的那幾個坑
- 4.自建的專案,一定要遷移資料庫,再執行專案