前後端分離djangorestframework—— 接入第三方的驗證碼平臺

来源:https://www.cnblogs.com/yangva/archive/2019/03/10/10507488.html
-Advertisement-
Play Games

因為極驗官網給的是用session作為驗證的,而我們做前後端分離的用的是token,而不是session,所以對於目前來說就不適用了,所以需要根據具體業務邏輯來改動。當然,大佬可以直接忽略 好的,直接上例子: 還是用的 Python高級應用(3)—— 為你的項目添加驗證碼 這文章最後的Lo... ...


關於驗證碼部分,在我這篇文章里說的挺詳細的了:Python高級應用(3)—— 為你的項目添加驗證碼

 

這裡還是再給一個前後端分離的實例,因為極驗官網給的是用session作為驗證的,而我們做前後端分離的用的是token,而不是session,所以對於目前來說就不適用了,所以需要根據具體業務邏輯來改動。當然,大佬可以直接忽略

 

好的,直接上例子:

還是用的 Python高級應用(3)—— 為你的項目添加驗證碼 這文章最後的LoginAuth例子,這裡改成使用djagnorestframwork的項目:

url沒變:

 

view也只是做了稍微的小改動,改動部分就是我標記出來的部分,因為不能用session,所以這裡採用redis存儲數據並獲取數據,有關redis配置請移步:資料庫之redis篇(3)—— Python操作redis

 

 

 

html,只改了兩處的請求地址,寫成了絕對地址

 

在啟動項目之前,需要設置一個中間件,不然會有跨域請求問題,有跨域請求解決問題,請移步:前後端分離djangorestframework——解決跨域請求  這裡就不多介紹了

在utils目錄下創建一個中間件,定義類名Mycors

配置文件里導入:

 

註意,由於已經設置了中間件添加允許請求頭,那個csrf的中間件就可以不用管,當然你註釋掉也沒有問題

 

 

啟動項目:

 

然後再pycharm下,單獨對html文件啟動,作為一個客戶端來訪問:

 

 點擊驗證碼:

沒有問題

 

相關代碼:

from django.contrib import admin
from django.urls import re_path, path
from generic.views import AuthView,GtView

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

    re_path(r'^pc-geetest/register', GtView.as_view()),
    re_path(r'^pc-geetest/validate', GtView.as_view()),
    path('auth/', AuthView.as_view()),
]
urls
# coding:utf-8
from rest_framework.views import APIView
from django.shortcuts import render
from django.http import HttpResponse
from utils.geetest import GeetestLib
import redis
import json

pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"
CONN = redis.Redis(host='127.0.0.1')  # 前提自己安裝上redis並配置好可以連接

class AuthView(APIView):
    def get(self, request):
        return render(request, "index.html")

class GtView(APIView):
    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
        CONN.set(gt.GT_STATUS_SESSION_KEY, status)
        CONN.set("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"]
        status = CONN.get(gt.GT_STATUS_SESSION_KEY)
        user_id = CONN.get("user_id")
        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        result = {"status": "success"} if result else {"status": "fail"}
        return HttpResponse(json.dumps(result))
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="http://127.0.0.1:8002/pc-geetest/validate" method="post">
    <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: "http://127.0.0.1:8002/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
from django.utils.deprecation import MiddlewareMixin


class MyCors(MiddlewareMixin):
    def process_response(self, request, response):
        response["Access-Control-Allow-Origin"] = "*"
        if request.method == "OPTIONS":
            response["Access-Control-Allow-Headers"] = "content-type"
        return response
middleware中間件

 

 

好的,這樣的感覺還是在搬磚,用的別人的代碼,再來一個使用vue作為前端主要代碼,對html文件做大的改寫

這次是用的是極驗給第一個案例,彈出式的:

 

 

同樣的,除了html文件,其他沒做多大改動:

url:

view,redis自己記著配置就行,還要註意的是這次這裡用的request.data,不是request.POST了,我在這裡耗了好久

 

 

html:

 

 啟動項目,解釋一下,不知道是不是我的瀏覽器顯示比例的問題,我只要用自己的id和key,它這個驗證碼按鈕就會跑到左邊去,我試了用官方給的示例id和key就正常,如果你們也遇到就自己去調試css了,這裡暫且這樣了

 

 

 點擊驗證:

 沒有問題:

 

 

相關代碼:

 

from django.shortcuts import render
from rest_framework.views import APIView
import redis
from utils.geetest import GeetestLib
from django.http import HttpResponse
import json

# Create your views here.

pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"
CONN = redis.Redis(host='127.0.0.1')  # 前提自己安裝上redis並配置好可以連接

class AuthView(APIView):
    def get(self, request):
        return render(request, "index.html")


class GtView(APIView):
    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
        CONN.set(gt.GT_STATUS_SESSION_KEY, status)
        CONN.set("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.data.get(gt.FN_CHALLENGE, '')
        validate = request.data.get(gt.FN_VALIDATE, '')
        seccode = request.data.get(gt.FN_SECCODE, '')
        # status = request.session[gt.GT_STATUS_SESSION_KEY]
        # user_id = request.session["user_id"]
        status = CONN.get(gt.GT_STATUS_SESSION_KEY)
        user_id = CONN.get("user_id")
        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        result = {"status": "success"} if result else {"status": "fail"}
        return HttpResponse(json.dumps(result))
view
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="http://static.geetest.com/static/tools/gt.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script>
    <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>
<div id="app">
    <div class="popup">
        <h2>django rest framework 中測試極驗 </h2>
        <br>
        <p>
            <label>用戶名:</label>
            <input id="username1" class="inp" type="text" value="極驗驗證" v-model="username">
        </p>
        <br>
        <p>
            <label>密&nbsp;&nbsp;&nbsp;&nbsp;碼:</label>
            <input id="password1" class="inp" type="password" value="123456" v-model="pwd">
        </p>

        <br>
        <input class="btn" id="popup-submit" type="submit" value="提交" ref="popup">

        <div id="popup-captcha"></div>
    </div>
</div>
<script>
    // Vue.prototype.$axios = axios;
    const app = new Vue({
        el: "#app",
        data: {
            username: "極驗驗證",
            pwd: "123456"
        },
        mounted() {
            let that = this;

            // 驗證開始需要向網站主後臺獲取id,challenge,success(是否啟用failback)
            axios.request({
                url: "http://127.0.0.1:8002/pc-geetest/register?t=" + (new Date()).getTime(), // 加隨機數防止緩存
                method: "get",
            }).then(function (data) {
                console.log(data.data);
                // 使用initGeetest介面
                // 參數1:配置參數
                // 參數2:回調,回調的第一個參數驗證碼對象,之後可以使用它做appendTo之類的事件
                initGeetest({
                    gt: data.data.gt,
                    challenge: data.data.challenge,
                    product: "popup", // 產品形式,包括:float,embed,popup。註意只對PC版驗證碼有效
                    offline: !data.data.success, // 表示用戶後臺檢測極驗伺服器是否宕機,一般不需要關註
                    new_captcha: true
                    // 更多配置參數請參見:http://www.geetest.com/install/sections/idx-client-sdk.html#config
                }, function (captchaObj) {
                    // 成功的回調
                    console.log("進入成功的回調");
                    captchaObj.onSuccess(function () {
                        let validate = captchaObj.getValidate();
                        axios.request({
                            url: "http://127.0.0.1:8002/pc-geetest/ajax_validate", // 進行二次驗證
                            method: "post",
                            data: {
                                username: that.username,
                                password: that.pwd,
                                geetest_challenge: validate.geetest_challenge,
                                geetest_validate: validate.geetest_validate,
                                geetest_seccode: validate.geetest_seccode
                            }
                        }).then(function (data) {
                            console.log(data.data);
                            if (data && (data.data.status === "success")) {
                                alert("登錄成功")
                            } else {
                                alert("登錄失敗")
                            }
                        })
                    });
                    console.log(that.$refs.popup);
                    that.$refs.popup.onclick = function () {
                        captchaObj.show();
                    };
                    // 將驗證碼加到id為captcha的元素里
                    captchaObj.appendTo("#popup-captcha");
                    // 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html
                });
            })


        }

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

(其他沒做任何改動,同上)

 

好的,完事兒了。感興趣的可以把極驗給的三個驗證碼都由之前的jquery改成vue試試,哈哈

 

總結:

說白了還是那一套官方給你的案例,根據自己實際情況改來改去就行了,不過得看得懂極驗給的demo才可以隨意改動

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MVC、MVP和MVVM這些開發模式為了分離視圖(View)和模型(Model)而提出來的,直白說就是為了前後端分離。 1. MVC(Model View Controller)模式 MVC是比較直觀的架構模式,即用戶操作 → View(負責接收用戶的輸入操作)→ Controller(業務邏輯處理 ...
  • 微服務架構的概述 應用架構的發展 應用是可以獨立運行的程式代碼,提供相對完善的業務功能. 目前的軟體架構有三種架構類型: 業務架構 應用架構 技術架構 他們之間的甚是: 業務架構決定應用架構,技術架構支撐著應用架構. 應用架構的發展歷程: 單體架構: 最古老的單體應用,沒有任何應用拆分,整體就是一個 ...
  • 由於拷貝後文檔格式有變, 僅摘幾段如下. 完整而且代碼帶語法高亮的源版在: "program in chinese/Programming_in_Scala_study_notes_zh" 前言: 本書已有中文版, 此筆記並不是對原教程的翻譯, 而是圍繞示例進行選摘, 並順便將所有示例改成中文命名( ...
  • 註: 本文僅對個人嘗試作一小結, 專欄中其他作者的嘗試還望各自總結 對自研中文編程語言的嘗試也許始於 "2015年" 對CoffeeScript的部分關鍵詞漢化和 "Java實現的彙編語言編譯器" 的開發. "2017年10月那場請求C 提供漢化版的討論" 也給了更多的動力. 之後對 "開源非英文關 ...
  • 報這個錯誤是因為我的 application_context.service.xml 文件里的的dubbo聲明暴露口時的ref屬性寫錯了。 ...
  • 這段時間在學習Spring,依賴註入DI和麵向切麵編程AOP是Spring框架最核心的部分。這次主要是總結依賴註入的bean的裝配方式。 什麼是依賴註入呢?也可以稱為控制反轉,簡單的來說,一般完成稍微複雜的業務邏輯,可能需要多個類,會出現有些類要引用其他類的實例,也可以稱為依賴其他類。傳統的方法就是 ...
  • 晚上在閱讀go lang的資料時突然想到一個問題,go是如何分配變數的記憶體結構的呢?好在網上的一篇文章做了透徹的分析見【go語言局部變數分配在棧還是堆】。 其結論是go語言局部變數的分配是由編譯器決定的。go語言編譯器會自動決定把一個變數放在棧還是放在堆,編譯器會做逃逸分析(escape analy ...
  • 忙瘋警告,這兩天可能進度很慢,下午打了一下午訓練賽,訓練賽的題我就不拿過來的,pta就做了一點點,明天又是滿課的一天,所以進度很慢啦~ L1-021 重要的話說三遍 這道超級簡單的題目沒有任何輸入。 你只需要把這句很重要的話 —— “I'm gonna WIN!”——連續輸出三遍就可以了。 註意每遍 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...