Python高級應用(3)—— 爲你的項目添加驗證碼

驗證碼簡介

驗證碼的做用:

驗證碼在如今來講,是很常見的東西,能夠必定程度的保護網站,好比防止網絡爬蟲惡意爬取網站數據啊,減小低級的攻擊啊什麼的。可是高級點的騷操做仍是不太好防範,因此如今的驗證碼平臺也在升級強化,爲了把人和機器嚴格分開。可是這東西,永遠都是看哪一方技術高低的,誰的技術高級,誰就能幹倒另外一方了。詳細的就不說了,總而言之,驗證碼能夠說是目前全部的面向用戶的平臺都會用到的,因此這項技能必須得會啊。javascript

 

 

使用Python庫自定義驗證碼

要本身定義驗證碼,就得使用pillow庫,先用pip install pillow 安裝,安裝步驟就略過了 css

這裏就直接給一個demo做爲講解,建立一個簡單的django項目,項目名爲LoginAuth,app名爲generichtml

 

 

初版,圖片存在磁盤裏

 

url:
前端

get_validCode_Img就是獲取驗證碼的路由 java

 

view:python

 

  • get_random_color是獲取隨機的三個顏色,由於三原色(三基色,具體哪一個不深究,這不是重點)就能夠組成全部的顏色,因此這裏用random隨機生成不一樣的顏色
  • get_valid_code_img視圖函數就是利用了pillow庫的功能
  • Image是pillow的畫板,ImageDraw是是畫筆,ImageFont是字體,我這用的字體是windows電腦自帶的arial.ttf,大家也能夠去網上下載那種很炫酷的字體放進去,注意路徑就行 
  • ImageDraw.draw.text就是寫字的用法,第一個參數是寫字的位置,第二個參數就是要寫的具體數據
  • chr()函數能夠將整形數字轉爲字母,但必須與ASCII碼對應,否則容易有問題
  • 最後的Image.save就是將剛纔的畫好的數據保存到一個文件,這個文件固然得是二進制的格式了,而後再讀出來返回,這裏估計有朋友會想,我塔碼的不能夠直接把剛纔的數據返回嗎?不存到圖片直接返回,你能夠試試,你找找Image對象在沒保存以前有沒有能夠讀取它的數據的方法  /滑稽

 

其餘的有關pillow庫的具體方法就很少說了,感興趣本身去研究了jquery

 

 

html模板文件,login.html,我引入了bootstrap的cdn,而後用了bt的css樣式,在驗證碼部分,直接用src請求訪問,這裏有點jsonp的意思web

 

啓動項目,打開/login頁面,端口綁定的8002ajax

OJBK 數據庫

 

第二版,存在內存IO裏

可是,就剛纔圖片那裏,若是之後項目上線,供多個帳戶使用,不一樣時段都有不少的帳戶訪問,登陸平臺,那麼這個圖片咱們知道直接就保存在當前目錄裏:

 

這樣的話就很佔空間了,因此咱們能夠利用IO模塊,將這個圖片直接存在內存裏,不存在磁盤上

 

只修改視圖函數的部分,其餘沒有作任何改動:

 

所有代碼:

from django.contrib import admin
from django.urls import re_path, path
from generic.views import login, get_valid_code_img

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', login),
    path('get_validCode_img/', get_valid_code_img),

]
urls
# coding:utf-8
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.contrib import auth
from PIL import Image, ImageDraw, ImageFont
import random
import io


def get_random_color():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))


def get_valid_code_img(request):
    # 方式1 :
    img = Image.new("RGB", (270, 40), color=get_random_color())
    draw = ImageDraw.Draw(img)
    arial_font = ImageFont.truetype("arial.ttf", size=26)
    valid_code_str = ""
    for i in range(5):
        random_num = str(random.randint(0, 9))
        random_low_alpha = chr(random.randint(95, 122))
        random_upper_alpha = chr(random.randint(65, 90))
        random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])
        draw.text((i * 50 + 20, 5), random_char, get_random_color(), font=arial_font)
        # 保存驗證碼字符串
        valid_code_str += random_char
    # with open("validCode.png", "wb") as f:
    #     img.save(f, "png")
    # with open("validCode.png", "rb") as f:
    #     data = f.read()
    f = io.BytesIO()
    img.save(f, "png")
    data = f.getvalue()
    return HttpResponse(data)


def login(request):
    if request.method == "POST":
        response = {"user": None, "msg": None}
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        valid_code = request.POST.get("valid_code")
        valid_code_str = request.session.get("valid_code_str")
        if valid_code.upper() == valid_code_str.upper():
            user = auth.authenticate(username=user, password=pwd)
            if user:
                auth.login(request, user)  # request.user== 當前登陸對象
                response["user"] = user.username
            else:
                response["msg"] = "用戶名或者密碼錯誤!"
        else:
            response["msg"] = "驗證碼錯誤!"
        return JsonResponse(response)
    return render(request, "login.html")
views
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陸</title>

    <script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
    <h3 class="btn btn-danger">用戶登陸</h3>
    <div class="row">
        <div class="col-md-4 col-lg-offset-4">
            <form action="" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="user">用戶名:</label>
                    <input type="text" id="user" class="form-control" name="user">
                </div>
                <div class="form-group">
                    <label for="pwd">密&nbsp;&nbsp;&nbsp;&nbsp;碼:</label>
                    <input type="password" id="pwd" class="form-control" name="pwd">
                </div>

                <div class="form-group">
                    <label for="valid_code">驗證碼</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" class="form-control" id="valid_code">
                        </div>
                        <div class="col-md-6">
                            <img width="170" height="30" id="valid_code_img" src="/get_validCode_img/" alt="">
                        </div>
                    </div>
                </div>

                <p class="error"></p>
                <input type="button" class="btn btn-primary login_btn btn-block" value="當即登陸">
            </form>
        </div>
    </div>
</div>

</body>
</html>
login.html

 

第三版,驗證碼添加噪點噪線

由於如上的圖片是很容易被機器識別的,因此爲了增長識別難度,能夠添加噪點噪線

 其中把驗證碼存入request.sessoin是爲了作比對驗證的,這裏就很少說了

 

啓動項目:

 

好的,這就是添加了噪點噪線

 

代碼(其餘沒變,只改了生成驗證碼的函數):

# coding:utf-8
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.contrib import auth
from PIL import Image, ImageDraw, ImageFont
import random
import io


def get_random_color():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))


def get_valid_code_img(request):
    # 方式1 :
    img = Image.new("RGB", (270, 40), color=get_random_color())
    draw = ImageDraw.Draw(img)
    arial_font = ImageFont.truetype("arial.ttf", size=26)
    valid_code_str = ""
    for i in range(5):
        random_num = str(random.randint(0, 9))
        random_low_alpha = chr(random.randint(95, 122))
        random_upper_alpha = chr(random.randint(65, 90))
        random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])
        draw.text((i * 30 + 30, 0), random_char, get_random_color(), font=arial_font)
        # 保存驗證碼字符串
        valid_code_str += random_char
    width = 170
    height = 30
    # 噪線
    for i in range(3):  # 三條線,也能夠更多
        x1 = random.randint(0, width)
        x2 = random.randint(0, width)
        y1 = random.randint(0, height)
        y2 = random.randint(0, height)
        draw.line((x1, y1, x2, y2), fill=get_random_color())
    # 噪點
    for i in range(50): # 50個噪點,也能夠更多
        draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
    # 登陸驗證相關
    request.session["valid_code_str"] = valid_code_str
    request.session['count'] = 0
    # with open("validCode.png", "wb") as f:
    #     img.save(f, "png")
    # with open("validCode.png", "rb") as f:
    #     data = f.read()
    f = io.BytesIO()
    img.save(f, "png")
    data = f.getvalue()
    return HttpResponse(data)


def login(request):
    if request.method == "POST":
        response = {"user": None, "msg": None}
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        valid_code = request.POST.get("valid_code")
        valid_code_str = request.session.get("valid_code_str")
        if valid_code.upper() == valid_code_str.upper():
            user = auth.authenticate(username=user, password=pwd)
            if user:
                auth.login(request, user)  # request.user== 當前登陸對象
                response["user"] = user.username
            else:
                response["msg"] = "用戶名或者密碼錯誤!"
        else:
            response["msg"] = "驗證碼錯誤!"
        return JsonResponse(response)
    return render(request, "login.html")
views

 

第四版,點擊驗證碼自動刷新

按照電腦常識,應該得有這個功能,點擊圖片刷新啊,由於看不清啊,就點擊刷新,可是若是刷新整個頁面的話,表單上已經填好的內容就沒了,因此,對了,搞前端的朋友估計更熟一點,用ajax異步請求,只讓圖片部分刷新就好了,方法是可行的,不過有個更好用的方法,爲地址後面加一個【?】便可,對了我下面那個ajax請求的是對用戶名和密碼的ajax請求驗證,並非對驗證碼的

 

 啓動項目:

 

一直點,它就一直作jsonp請求並刷新,是否是很方便?

相關代碼(跟上面的代碼比較只有html文件改了,其餘沒有變的)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陸</title>

    <script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
    <h3 class="btn btn-danger">用戶登陸</h3>
    <div class="row">
        <div class="col-md-4 col-lg-offset-4">
            <form action="" method="post">
                {% csrf_token %}
                <div class="form-group">
                    <label for="user">用戶名</label>
                    <input type="text" id="user" class="form-control" name="user">
                </div>
                <div class="form-group">
                    <label for="pwd">密碼</label>
                    <input type="password" id="pwd" class="form-control" name="pwd">
                </div>

                <div class="form-group">
                    <label for="valid_code">驗證碼</label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" class="form-control" id="valid_code">
                        </div>
                        <div class="col-md-6">
                            <img width="170" height="30" id="valid_code_img" src="/get_validCode_img/" alt="">
                        </div>
                    </div>
                </div>

                <p class="error"></p>
                <input type="button" class="btn btn-primary login_btn btn-block" value="當即登陸">
            </form>
        </div>
    </div>
</div>

</body>
<script type="text/javascript">
    $(function(){
        $('#valid_code_img').click(function(){
            $(this)[0].src += '?'
        });

        {#定義一個ajax請求函數#}
        function userlogin(){
            $.ajax({
                url:'',
                type:'POST',
                data:{
                    csrfmiddlewaretoken:$('input[name="csrfmiddlewaretoken"]').val(),
                    user:$('#user').val(),
                    pwd:$('#pwd').val(),
                    codeimg:$('#valid_code').val()
                },
                success:function(data){
                    if(data.user){
                        location.href ='/index';
                    }else{
                        $('#user').val('');
                        $('#pwd').val('');
                        $('.error').text(data.msg).css({
                                'color':'red',
                                'margin-left':'10px'
                            });
                        setTimeout(function () {
                           $('.error').text('');
                        },3000)
                    }
                },
            })
        }

        {# 監聽登陸按鈕#}
        $('.login_btn').click(function(){
            userlogin();
        });

        {# 監聽回車按鍵#}
        $('body').keydown(function(e){
            if(event.keyCode == 13){
              userlogin();
            }
        });

    })
</script>
</body>
</html>
login.html

 

自定義驗證碼就完了,你能夠考慮在實際項目上線時就用本身定義的這個驗證碼服務,可是我想你應該猜到了,這種的仍是不太好,畢竟仍是太簡單的驗證操做了(固然沒說不能夠用啊,根據本身的平臺選擇),如今利用Python作一個深度學習,三兩下就把你這個驗證碼搞定了,因此呢,還想更安全一點,可使用第三方的驗證碼平臺 

 

 

使用第三方的驗證碼

 

 

以下:

 

 經常使用的驗證碼平臺:

騰訊雲和阿里雲分別都有本身的驗證碼,而後就極驗,還有一些其餘的我叫不上名的,本教程按極驗的官方文檔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>密&nbsp;&nbsp;&nbsp;&nbsp;碼:</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">密&nbsp;&nbsp;&nbsp;&nbsp;碼:</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">密&nbsp;&nbsp;&nbsp;&nbsp;碼:</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

 

最後啓動訪問:

 

 

說明一下,這裏訪問時,去geetest官網請求須要一段時間,因此剛開始打開有正在加載驗證的字樣,等幾秒鐘就有了

 

點擊驗證:

 

 

 驗證成功的,後面的結果就不展現了

 

 

 

詳細的代碼,其實都沒改多少,就只是把本身的業務邏輯加上去了,其餘的都是直接用極驗官方的

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
<!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">密&nbsp;&nbsp;&nbsp;&nbsp;碼:</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模板文件
# 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):
        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)
views

 

 

 而後還有一些其餘的驗證方式,有手機頁面的,有先點提交再驗證驗證碼的,反正就本身去玩了,我以爲仍是挺簡單的 

 

關於極驗怎麼接入到先後端分離的djangorestframework項目的教程,請移步:先後端分離djangorestframework—— 接入第三方的驗證碼平臺

 

總結:

  • 1.自定義驗證碼不是不可用,能夠本身練練手,作圖形識別練習也是能夠的
  • 2.第三方驗證平臺,其實用多了第三方的平臺,基本就是那幾個步驟,下載sdk,融到本身代碼中,根據文檔配置參數,調整下就好了
  • 3.使用極驗加入自定義的項目時,必定要遷移數據庫,再運行項目,由於會用到django自帶的django_session表作session會話保存
相關文章
相關標籤/搜索