極驗驗證demo(django+vue)
在使用之前,曾經試過用阿里雲的人機驗證,不過在簽名部分比較複雜,下載sdk後需要自己寫很多,折騰了一下,還是放棄。而騰訊雲的人機驗證python版本有demo,直接填寫keyhe1secret就可以使用,但是demo使用的是web.py的框架,這個之前有了解過,比較好用,但是作者去世了,只有python2版本,沒有3的版本,想了一下即使修改成3的版本,還要做改成django的,有點麻煩。網易雲的宣傳上有vue版本的,而且效果看起來不錯,本來想試一下,但是註冊後還要官方通過驗證,等了1天還沒通過,就打算另找方法。
偶然翻看部落格,發現有人介紹geetest,看了一下感覺上手比較容易,sui遂註冊使用。
一、簡單註冊使用
geetest官網:https://www.geetest.com/
該公司主要是做驗證的。目前開放的是行為驗證。身份驗證還未開放。
註冊申請後,獲得id和key。在其github專案上下載相應語言和版本,就可使用。
文件看起來也比較清晰
老版本python sdk下載:https://github.com/GeeTeam/gt-python-sdk
新版本python sdk下載:https://github.com/GeeTeam/gt3-python-sdk
這兩個都可以使用python2.7以上的版本,區別在於驗證特性設定有些不同。需要注意的是django版本是1.8
根據之前專案的django是1.11.3版本,修改了sdk中報錯的部分程式碼。
下載之後執行setup.py檔案
在demo中發現python的三大主流框架都有,這真是太棒了呢
在django_demo資料夾中先安裝requirements.txt裡面需要的庫
注意:開啟django_demo下的settings.py檔案
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, "static"),
)
最後新增這部分,官方的內容給的是絕對路徑,我們需要拼接相對路徑
demo中的檔案替換自己專案中相應的檔案
執行後即可看到驗證頁面
二、vue和python部分結合
分析:後端中validate和ajax_validate區別是:返回頁面與返回資料
鑑於我們使用前後端分離的方式,在提交路徑上選擇ajax_validate
1.vue部分
(1)form-action屬性提交
python部分可用後,開啟demo中的index.html,將html部分放置在vue驗證元件的template中,將style放在vue的style中。
在根頁面的head區域引入jquery
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
開啟http://static.geetest.com/static/tools/gt.js複製全部內容到你的assets資源目錄下
在你的驗證元件頁面引入剛才複製的資源
import '../assets/js/gt.js'
在methods裡新建一個方法
拷貝demo.html中script裡ajax獲取資料的方法,在vue裡改為axios獲取
getCaptchaData () {
this.$axios.get('/api/register?t=' + (new Date()).getTime())
.then((res) => {
console.log('res', res)
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的元素裡
captchaObj.appendTo('#embed-captcha')
captchaObj.onReady(function () {
$('#wait')[0].className = 'hide'
})
// 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html
}
// 使用initGeetest介面
// 引數1:配置引數
// 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件
window.initGeetest({
gt: res.data.gt,
challenge: res.data.challenge,
product: 'embed', // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效
offline: !res.data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注
}, handlerEmbed)
})
.catch(function (error) {
console.log(error)
})
}
在建立時啟動
this.getCaptchaData()
附件:slidingBlock1.vue
<!-- slidingBlock1:form-action部分 -->
<template>
<form class="popup" action="http://127.0.0.1:8000/api/ajax_validate" method="post">
<p>
<label for="user">使用者名稱:</label>
<input class="inp" id="user" type="text" value="極驗驗證">
</p>
<br>
<p>
<label for="password">密 碼:</label>
<input class="inp" id="password" 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>
</template>
<script>
import '../assets/js/gt.js'
export default {
name: 'slidingBlock1',
data () {
return {
}
},
mounted () {
this.getCaptchaData()
},
components: {
},
methods: {
login () {
let data = this.$qs.stringify(this.form)
let that = this
this.$axios.post('api/ajax_validate', data, {withCredentials: true
})
.then((res) => {
console.log(res)
})
.catch(function () {
that.$message.error('賬號名或密碼錯誤') // catch裡的this不是vue物件,需要外層設定
})
},
getCaptchaData () {
this.$axios.get('/api/register?t=' + (new Date()).getTime())
.then((res) => {
console.log('res', res)
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的元素裡
captchaObj.appendTo('#embed-captcha')
captchaObj.onReady(function () {
$('#wait')[0].className = 'hide'
})
// 更多介面參考:http://www.geetest.com/install/sections/idx-client-sdk.html
}
// 使用initGeetest介面
// 引數1:配置引數
// 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件
window.initGeetest({
gt: res.data.gt,
challenge: res.data.challenge,
product: 'embed', // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效
offline: !res.data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注
}, handlerEmbed)
})
.catch(function (error) {
console.log(error)
})
}
}
}
</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;
}
</style>
這裡axio獲得資料使用代理的方式
列印獲取的資料
使用vuex的,可以結合參考文件1使用
(2)form-methods提交按鈕提交
為了區別,將驗證碼解除安裝id為captcha的容器裡
var handlerEmbed = function (captchaObj) {
captchaObj.appendTo('#captcha')
captchaObj.onReady(function () {
document.getElementById('wait').style.display = 'none'
})
captchaObj.onSuccess(function () {
_this.form.isDisabled = !_this.isDisabled
_this.form.writeCode = !_this.writeCode
_this.form.geetest_challenge = captchaObj.getValidate().geetest_challenge
_this.form.geetest_validate = captchaObj.getValidate().geetest_validate
_this.form.geetest_seccode = captchaObj.getValidate().geetest_seccode
console.log(_this.form)
})
captchaObj.onError(function () {
console.log('出錯啦,提示使用者稍後進行重試')
})
}
主要是在回撥函式的initGeetest部分重寫handlerEmbed,將回調的部分資料加入post資料裡
注意:刪除提交按鈕型別
login () {
let data = this.$qs.stringify(this.form)
console.log(data)
let that = this
this.$axios.post('/api/ajax_validate/', data, {withCredentials: true
})
.then((res) => {
console.log(res)
if (res.data.status === 'fail') {
$('#notice')[0].className = 'show'
setTimeout(function () {
$('#notice')[0].className = 'hide'
}, 2000)
}
})
.catch(function () {
that.$message.error('賬號名或密碼錯誤') // catch裡的this不是vue物件,需要外層設定
})
},
新增登入按鈕方法,對返回的結果進行判斷,通過隱藏/顯示來提示使用者驗證碼情況
附件:slidingBlock2.vue
<!-- slidingBlock2:form-methods部分 -->
<template>
<form class="popup" method="post">
<p>
<label for="user">使用者名稱:</label>
<input class="inp" id="user" type="text" :value="form.username">
</p>
<br>
<p>
<label for="password">密 碼:</label>
<input class="inp" id="password" type="password" :value="form.password">
</p>
<div id="embed-captcha"></div>
<div id="captcha"></div>
<p id="wait" class="show">正在載入驗證碼......</p>
<p id="notice" class="hide">請先拖動驗證碼到相應位置</p>
<br>
<input class="btn" id="embed-submit" value="提交" v-on:click="login()">
</form>
</template>
<script>
import '../assets/js/gt.js'
export default {
name: 'slidingBlock2',
data () {
return {
form: {
username: '極驗驗證',
password: '123456',
isDisabled: true,
writeCode: true
}
}
},
mounted () {
this.getCaptchaData()
},
components: {
},
methods: {
login () {
let data = this.$qs.stringify(this.form)
console.log(data)
let that = this
this.$axios.post('/api/ajax_validate/', data, {withCredentials: true
})
.then((res) => {
console.log(res)
if (res.data.status === 'fail') {
$('#notice')[0].className = 'show'
setTimeout(function () {
$('#notice')[0].className = 'hide'
}, 2000)
}
})
.catch(function () {
that.$message.error('賬號名或密碼錯誤') // catch裡的this不是vue物件,需要外層設定
})
},
getCaptchaData () {
let _this = this
this.$axios.get('/api/register?t=' + (new Date()).getTime())
.then((res) => {
console.log('res', res)
var handlerEmbed = function (captchaObj) {
captchaObj.appendTo('#captcha')
captchaObj.onReady(function () {
document.getElementById('wait').style.display = 'none'
})
captchaObj.onSuccess(function () {
_this.form.isDisabled = !_this.isDisabled
_this.form.writeCode = !_this.writeCode
_this.form.geetest_challenge = captchaObj.getValidate().geetest_challenge
_this.form.geetest_validate = captchaObj.getValidate().geetest_validate
_this.form.geetest_seccode = captchaObj.getValidate().geetest_seccode
console.log(_this.form)
})
captchaObj.onError(function () {
console.log('出錯啦,提示使用者稍後進行重試')
})
}
// 使用initGeetest介面
// 引數1:配置引數
// 引數2:回撥,回撥的第一個引數驗證碼物件,之後可以使用它做appendTo之類的事件
window.initGeetest({
gt: res.data.gt,
challenge: res.data.challenge,
product: 'embed', // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效
offline: !res.data.success // 表示使用者後臺檢測極驗伺服器是否宕機,一般不需要關注
}, handlerEmbed)
})
.catch(function (error) {
console.log(error)
})
}
}
}
</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;
}
</style>
可以得到返回成功的資訊
後端結合使用框架的註冊、登入部分修改程式碼(略)
三、其他
在查詢的過程中,網上有不少使用python和selenium庫破解極驗證的(B站就是),方法主要是使用庫對圖片進行灰度處理,識別圖片,找到拼圖範圍,滑動座標達到。所以這種驗證不是非常安全。有時間再看看有沒其他更好用的人機驗證
參考文件:
1.vue2.0 + 極驗驗證:https://blog.csdn.net/XiaoYi0215/article/details/79921967?utm_source=blogxgwz0