uniCloud 是 DCloud 聯(lián)合阿里云、騰訊云,為開發(fā)者提供的基于 serverless 模式和 js 編程的云開發(fā)平臺。
官方文檔:https://uniapp.dcloud.net.cn/uniCloud/uni-captcha.html
下載地址:https://ext.dcloud.net.cn/plugin?id=4048
GitCode 倉庫:https://gitee.com/dcloud/uni-captcha
圖形驗證碼主要起到人機(jī)校驗或其他限制調(diào)用的作用,如:
防止機(jī)器冒充人類做暴力破解
防止大規(guī)模在線注冊濫用服務(wù)
防止濫用在線批量操作
防止信息被大量采集聚合
常見的業(yè)務(wù)場景有:
注冊環(huán)節(jié):防止無效垃圾注冊,從源頭進(jìn)行管理
登錄環(huán)節(jié):防止撞庫攻擊、暴力破解,保障用戶數(shù)據(jù)
短信防刷:減少短信接口被刷情況,減少企業(yè)不必要成本
互動環(huán)節(jié):防止批量垃圾互動信息,破壞用戶UGC內(nèi)容生態(tài)
激勵領(lǐng)?。悍乐贡慌咳煅蛎?/p>
組成部分
數(shù)據(jù)表:opendb-verify-codes,用于存儲驗證碼相關(guān)數(shù)據(jù)
公共模塊:uni-captcha,集成獲取、刷新、校驗驗證碼
云對象:uni-captcha-co,集成獲取驗證碼的api
云端一體組件:uni-captcha和uni-popup-captcha,集成創(chuàng)建、刷新、顯示驗證碼
原理時序
客戶端,向服務(wù)端請求某一應(yīng)用場景的驗證碼。提示:這里用場景值scene,表示應(yīng)用場景,用于防止不同功能的驗證碼混用,如:login、pay
服務(wù)端,創(chuàng)建驗證碼,即:向數(shù)據(jù)表opendb-verify-codes中創(chuàng)建狀態(tài)為待驗證的驗證碼記錄(作廢同一個設(shè)備id和場景值的舊驗證碼記錄),并返回格式為base64的圖形驗證碼資源數(shù)據(jù)。提示:這里的數(shù)據(jù)表,狀態(tài)字段名:state用0表示待驗證,用2表示已作廢。
客戶端,得到驗證碼圖片,用戶識別后輸入驗證碼的值與表單數(shù)據(jù)一起提交至服務(wù)端
服務(wù)端,云函數(shù)或clientDB action中校驗驗證碼,決定是否執(zhí)行業(yè)務(wù)邏輯。如果驗證碼錯誤則返回錯誤信息,客戶端再重復(fù)步驟1-3。提示:驗證驗證碼,可以使用封裝好的公共模塊的verify方法詳情,也可以直接查庫校驗。
一、創(chuàng)建Demo
首先我們創(chuàng)建一個uni-app的demo,來演示功能效果。首先打開HBuilderX,選擇:文件->新建->項目->uni-app,選擇模板uni-ui項目,如下圖:

二、創(chuàng)建云函數(shù)
Demo創(chuàng)建好后,我們來創(chuàng)建uni-captcha云函數(shù),如下圖右擊cloudfunctions,選擇新建云函數(shù)/云對象。


彈出如下圖后,我們選擇uni-captcha即可,點擊確認(rèn)。

然后cloudfunctions中,則會生成common/uni-captcha和uni-captcha-co兩個模塊。這時我們先到此為止,后續(xù)使用到云函數(shù)再作詳解。

此時別忘記將其上傳部署,分別將1,2,3三項右擊選擇上傳。

三、創(chuàng)建login登錄頁
demo和云函數(shù)都創(chuàng)建成功后,我們實現(xiàn)一個簡單的登錄頁面,如下圖:

這里我們使用普通驗證碼組件uni-captcha,代碼如下:
<template>
<view class="login-wrap">
<uni-forms ref="form" :modelValue="formData" :rules="rules">
<uni-forms-item required label="賬號" name="name">
<uni-easyinput type="text" v-model="formData.name" placeholder="請輸入姓名" />
</uni-forms-item>
<uni-forms-item required label="密碼" name="password">
<uni-easyinput type="password" v-model="formData.password" placeholder="請輸入姓名" />
</uni-forms-item>
<uni-forms-item required name="captcha" label="驗證碼">
<uni-captcha :scene="formData.scene" v-model="formData.captcha"></uni-captcha>
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submitForm">登錄</button>
</view>
</template>
<script>
export default {
data() {
return {
formData:{
captcha:"",
scene:"login"
},
rules: {}
}
},
methods: {
submitForm(){
}
}
}
</script>
<style lang="scss">
.login-wrap{
padding: 30rpx;
}
</style>
四、表單校驗
uni-forms 需要通過 rules 屬性傳入約定的校驗規(guī)則。如果你對uni擴(kuò)展組件還不了解的,可以去官網(wǎng)查看。
地址:https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
4.1 必填校驗
data中rules添加表單中字段必填項,代碼如下:
rules: {
name: {
rules: [
{ required: true, errorMessage: '請輸入姓名' }
]
},
password: {
rules: [
{ required: true, errorMessage: '請輸入密碼' }
]
},
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗證碼' }
]
}
}
然后在methods方法中,給提交函數(shù)添加表單校驗執(zhí)行函數(shù),代碼如下:
submitForm(){
this.$refs.form.validate().then(res=>{
console.log('表單數(shù)據(jù)信息:', res);
}).catch(err =>{
console.log('表單錯誤信息:', err);
})
}
此時,點擊“登錄”按鈕,如果未填寫任務(wù)信息,則表單會提示相應(yīng)錯誤,如下圖:

4.2 創(chuàng)建云對象
此時我們創(chuàng)建一個云對象uni-captcha-demo,用于對表單中輸入的驗證碼,進(jìn)行校驗其是否正確。還是在cloudfunctions上右擊,選擇“新建云函數(shù)/云對象”,如下圖:

點擊創(chuàng)建后,cloudfunctions中會生成uni-captcha-demo云對象。如下圖:

此時可以在index.obj.js中添加圖形驗證碼校驗功能,返回校驗結(jié)果。代碼如下:
//導(dǎo)入驗證碼公共模塊
const uniCaptcha = require('uni-captcha')
//獲取數(shù)據(jù)庫對象
const db = uniCloud.database()
//獲取數(shù)據(jù)表opendb-verify-codes對象
const verifyCodes = db.collection('opendb-verify-codes')
module.exports = {
async verify({scene,captcha}) {
let res = await uniCaptcha.verify({scene,captcha})
return res;
}
}
同樣,uni-captcha-demo云對象完成后,也需要右擊選擇”上傳部署“。
4.3 驗證碼校驗
validateFunction 異步校驗:如果需要異步校驗,validateFunction 需要返回一個 Promise ,校驗不通過 執(zhí)行 reject(new Error('錯誤信息')) 返回對應(yīng)的錯誤信息,如果校驗通過則直接執(zhí)行 resolve() 即可,在異步校驗方法中,不需要使用 callback 。
首先我們在登錄頁引入云對象,代碼如下:
<script>
//引入uni-captcha-demo云對象
const uniCaptchaDemoCo = uniCloud.importObject("uni-captcha-demo");
export default {
data() {
return {
//...
}
},
methods: {
//...
}
}
</script>
在rules中添加異步校驗,代碼如下:
rules: {
//...
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗證碼' },
{ validateFunction: (rule, value, data, callback) => {
return new Promise((resolve, reject) => {
//調(diào)用verify函數(shù)進(jìn)行校驗
uniCaptchaDemoCo.verify(this.formData).then(e=>{
resolve();
}).catch(e => {
reject(new Error(e.errMsg));
});
})
} }
]
},
}
五、解決MODULE_NOT_FOUND
以上校驗功能已全部完成了,但此時大家會發(fā)現(xiàn),所有信息都填寫后,點擊“登錄“會報如下圖錯誤:

這是因為在創(chuàng)建云對象uni-captcha-demo時,內(nèi)部使用到了uni-captcha模塊,需要將其關(guān)聯(lián)上。在uni-captcha-demo上鼠標(biāo)右擊,選擇”管理公共模塊或擴(kuò)展庫依賴“
。

選擇”uni-captcha“公共模板,點擊確認(rèn)。然后再次右擊uni-captcha-demo選擇”上傳部署“即可。

以上步驟完成后,我們再次將驗證碼輸入錯誤,點擊”登錄“后則會顯示”驗證碼錯誤“,如下圖:

六、刷新驗證碼
另外,我們發(fā)現(xiàn)如果驗證碼錯誤后,顯示的驗證碼不會自動刷新。由于這里我們使用的是uni-app的擴(kuò)展UI組件,功能不好升級維護(hù),如果覺得此組件不好用,也可以自己使用uni-captcha-co獲取驗證進(jìn)行個性化操作。
這里主要是為了演示,就先在原基本上完成刷新功能。打開uni_modules目錄,找到uni-captcha組件,再打開components目錄中的uni-captcha,我們來看下內(nèi)部是如何實現(xiàn)的。

如上圖所示,我們發(fā)現(xiàn)應(yīng)用場景發(fā)生改變后,驗證碼會重新獲取。那我們對代碼進(jìn)行如下修改即可,代碼如下:
<script>
const uniCaptchaDemoCo = uniCloud.importObject("uni-captcha-demo");
//索引
let index = 0;
export default {
data() {
return {
formData:{
captcha:"",
scene:"login"
},
rules: {
//...
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗證碼' },
{ validateFunction: (rule, value, data, callback) => {
return new Promise((resolve, reject) => {
uniCaptchaDemoCo.verify(this.formData).then(e=>{
resolve();
}).catch(e => {
//修改場景值,重新獲取驗證碼
this.formData['scene'] = 'login'+(++index);
reject(new Error(e.errMsg));
});
})
} }
]
},
},
//rules end
}
},
methods: {
//...
}
}
</script>
七、公共模塊
云端一體組件uni-captcha和uni-popup-captcha,已經(jīng)集成公共模塊的獲取驗證碼接口,這里不使用組件模塊,直接通過接口獲取驗證碼和校驗功能。
在上面創(chuàng)建uni-captcha模塊時,已生成了uni-captcha-co云對象。

7.1 獲取驗證碼
uni-captcha-co云函數(shù)中,已實現(xiàn)了獲取驗證碼功能,直接調(diào)用即可,代碼如下:
index.obj.index代碼如下:
//導(dǎo)入驗證碼公共模塊
const uniCaptcha = require('uni-captcha')
//獲取數(shù)據(jù)庫對象
const db = uniCloud.database();
//獲取數(shù)據(jù)表opendb-verify-codes對象
const verifyCodes = db.collection('opendb-verify-codes');
module.exports = {
//獲取驗證碼
async getImageCaptcha({
scene
}) {
//獲取設(shè)備id
let {
deviceId,
platform
} = this.getClientInfo();
//根據(jù):設(shè)備id、場景值、狀態(tài),查找記錄是否存在
let res = await verifyCodes.where({
scene,
deviceId,
state: 0
}).limit(1).get();
//如果已存在則調(diào)用刷新接口,反之調(diào)用插件接口
let action = res.data.length ? 'refresh' : 'create';
//執(zhí)行并返回結(jié)果
//導(dǎo)入配置,配置優(yōu)先級說明:此處配置 > uni-config-center
return await uniCaptcha[action]({
scene, //來源客戶端傳遞,表示:使用場景值,用于防止不同功能的驗證碼混用
uniPlatform: platform
})
}
}
將前面登錄頁面引入的云對象更換成“uni-captcha-co”,然后定義getVerifyImage()函數(shù),獲取圖形驗證碼。
公共模塊中提供了刷新驗證碼功能,測試發(fā)現(xiàn)設(shè)備校驗這塊,本地模擬測試存在問題,所以這里未使用,有需要的可以自行研究。
頁面代碼如下:
<template>
<view class="login-wrap">
<uni-forms ref="form" :modelValue="formData" :rules="rules">
<uni-forms-item required label="賬號" name="name">
<uni-easyinput type="text" v-model="formData.name" placeholder="請輸入姓名" />
</uni-forms-item>
<uni-forms-item required label="密碼" name="password">
<uni-easyinput type="password" v-model="formData.password" placeholder="請輸入姓名" />
</uni-forms-item>
<uni-forms-item required name="captcha" label="驗證碼">
<!-- uni-captch-box -->
<view class="uni-captch-box">
<uni-easyinput type="password" v-model="formData.captcha" placeholder="請輸入驗證碼" />
<image class="captcha-img" mode="aspectFill" :src="imgUrl" @click="getVerifyImage"></image>
</view>
<!-- /uni-captch-box -->
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submitForm">登錄</button>
</view>
</template>
<script>
const uniCaptchCo = uniCloud.importObject('uni-captcha-co');
export default {
data() {
return {
imgUrl: "",
formData:{
captcha:"",
scene:"login"
},
rules: {
name: {
rules: [
{ required: true, errorMessage: '請輸入姓名' }
]
},
password: {
rules: [
{ required: true, errorMessage: '請輸入密碼' }
]
},
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗證碼' }
]
},
},
//rules end
}
},
created() {
this.getVerifyImage();
},
methods: {
//獲取驗證碼
getVerifyImage(){
uniCaptchCo.getImageCaptcha({scene: this.formData.scene}).then(res => {
if(res.code==0){
this.imgUrl = res.captchaBase64;
}else{
uni.showToast({
icon: 'none',
title: res.message
});
}
}).catch(e => {});
},
//表單校驗
submitForm(){
this.$refs.form.validate().then(res=>{
console.log('表單數(shù)據(jù)信息:', res);
uni.showToast({
icon: 'none',
title: '校驗成功~'
});
}).catch(err =>{
// console.log('表單錯誤信息:', err);
})
}
}
}
</script>
<style lang="scss">
.login-wrap{
padding: 30rpx;
}
.uni-captch-box{ position: relative; padding-right: 240rpx;
.captcha-img{ width: 200rpx; height: 70rpx; border: 3rpx solid #F0F0F0; border-radius: 5rpx; position: absolute; top: 0; right: 0; z-index: 10; background-color: #aaa; }
}
</style>
此時,頁面布局可以根據(jù)需求來實現(xiàn)圖形驗證,頁面效果圖下:

7.2校驗驗證碼
把校驗驗證碼功能函數(shù)拷到uni-captcha-co/index.obj.js中,代碼如下:
// 開發(fā)文檔: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
//導(dǎo)入驗證碼公共模塊
const uniCaptcha = require('uni-captcha')
//獲取數(shù)據(jù)庫對象
const db = uniCloud.database();
//獲取數(shù)據(jù)表opendb-verify-codes對象
const verifyCodes = db.collection('opendb-verify-codes');
module.exports = {
//校驗驗證碼
async verify({scene,captcha}) {
let res = await uniCaptcha.verify({scene,captcha})
return res;
},
//獲取驗證碼
//...
}
這里將前面實現(xiàn)的rules校驗,修改成uni-captcha-co對象uniCaptchCo即可,如下:文章來源:http://www.zghlxwxcb.cn/news/detail-480296.html
rules: {
//...
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗證碼' },
{ validateFunction: (rule, value, data, callback) => {
return new Promise((resolve, reject) => {
//調(diào)用verify函數(shù)進(jìn)行校驗
uniCaptchCo.verify(this.formData).then(e=>{
resolve();
}).catch(e => {
reject(new Error(e.errMsg));
});
})
} }
]
},
}
以上僅供參考,有更好解決方案,歡迎大家分享!文章來源地址http://www.zghlxwxcb.cn/news/detail-480296.html
到了這里,關(guān)于uni-app使用uniCloud實現(xiàn)圖形驗證碼(uni-captcha)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!