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

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


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

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

此時(shí)別忘記將其上傳部署,分別將1,2,3三項(xiàng)右擊選擇上傳。

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

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

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

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

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

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

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

以上步驟完成后,我們再次將驗(yàn)證碼輸入錯(cuò)誤,點(diǎn)擊”登錄“后則會(huì)顯示”驗(yàn)證碼錯(cuò)誤“,如下圖:

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

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

7.1 獲取驗(yàn)證碼
uni-captcha-co云函數(shù)中,已實(shí)現(xiàn)了獲取驗(yàn)證碼功能,直接調(diào)用即可,代碼如下:
index.obj.index代碼如下:
//導(dǎo)入驗(yàn)證碼公共模塊
const uniCaptcha = require('uni-captcha')
//獲取數(shù)據(jù)庫對(duì)象
const db = uniCloud.database();
//獲取數(shù)據(jù)表opendb-verify-codes對(duì)象
const verifyCodes = db.collection('opendb-verify-codes');
module.exports = {
//獲取驗(yàn)證碼
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)先級(jí)說明:此處配置 > uni-config-center
return await uniCaptcha[action]({
scene, //來源客戶端傳遞,表示:使用場景值,用于防止不同功能的驗(yàn)證碼混用
uniPlatform: platform
})
}
}將前面登錄頁面引入的云對(duì)象更換成“uni-captcha-co”,然后定義getVerifyImage()函數(shù),獲取圖形驗(yàn)證碼。
公共模塊中提供了刷新驗(yàn)證碼功能,測試發(fā)現(xiàn)設(shè)備校驗(yàn)這塊,本地模擬測試存在問題,所以這里未使用,有需要的可以自行研究。
頁面代碼如下:
<template>
<view class="login-wrap">
<uni-forms ref="form" :modelValue="formData" :rules="rules">
<uni-forms-item required label="賬號(hào)" 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="驗(yàn)證碼">
<!-- uni-captch-box -->
<view class="uni-captch-box">
<uni-easyinput type="password" v-model="formData.captcha" placeholder="請輸入驗(yàn)證碼" />
<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: '請輸入驗(yàn)證碼' }
]
},
},
//rules end
}
},
created() {
this.getVerifyImage();
},
methods: {
//獲取驗(yàn)證碼
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 => {});
},
//表單校驗(yàn)
submitForm(){
this.$refs.form.validate().then(res=>{
console.log('表單數(shù)據(jù)信息:', res);
uni.showToast({
icon: 'none',
title: '校驗(yàn)成功~'
});
}).catch(err =>{
// console.log('表單錯(cuò)誤信息:', 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>此時(shí),頁面布局可以根據(jù)需求來實(shí)現(xiàn)圖形驗(yàn)證,頁面效果圖下:

7.2校驗(yàn)驗(yàn)證碼
把校驗(yàn)驗(yàn)證碼功能函數(shù)拷到uni-captcha-co/index.obj.js中,代碼如下:
// 開發(fā)文檔: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
//導(dǎo)入驗(yàn)證碼公共模塊
const uniCaptcha = require('uni-captcha')
//獲取數(shù)據(jù)庫對(duì)象
const db = uniCloud.database();
//獲取數(shù)據(jù)表opendb-verify-codes對(duì)象
const verifyCodes = db.collection('opendb-verify-codes');
module.exports = {
//校驗(yàn)驗(yàn)證碼
async verify({scene,captcha}) {
let res = await uniCaptcha.verify({scene,captcha})
return res;
},
//獲取驗(yàn)證碼
//...
}這里將前面實(shí)現(xiàn)的rules校驗(yàn),修改成uni-captcha-co對(duì)象uniCaptchCo即可,如下:
rules: {
//...
captcha: {
rules: [
{ required: true, errorMessage: '請輸入驗(yàn)證碼' },
{ validateFunction: (rule, value, data, callback) => {
return new Promise((resolve, reject) => {
//調(diào)用verify函數(shù)進(jìn)行校驗(yàn)
uniCaptchCo.verify(this.formData).then(e=>{
resolve();
}).catch(e => {
reject(new Error(e.errMsg));
});
})
} }
]
},
}以上僅供參考,有更好解決方案,歡迎大家分享!
總結(jié)
到此這篇關(guān)于uni-app使用uniCloud實(shí)現(xiàn)圖形驗(yàn)證碼(uni-captcha)的文章就介紹到這了,更多相關(guān)uni-app實(shí)現(xiàn)圖形驗(yàn)證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)簡單小鋼琴有聲彈奏效果
用HTML5+javascript實(shí)現(xiàn)的小鋼琴,按下鋼琴鍵上的相應(yīng)字母用或用鼠標(biāo)點(diǎn)擊鋼琴鍵發(fā)聲,javascript代碼包含了對(duì)鼠標(biāo)按下、移動(dòng)和松開,以及鍵盤按下的事件監(jiān)聽2024-02-02
js如何比較兩個(gè)日期的時(shí)間大小簡單代碼示例
在JavaScript中,日期比較涉及評(píng)估兩個(gè)日期,以確定一個(gè)日期是早于、晚于另一個(gè)日期還是與另一個(gè)日期相同,這篇文章主要給大家介紹了關(guān)于js如何比較兩個(gè)日期的時(shí)間大小的相關(guān)資料,需要的朋友可以參考下2024-06-06
詳解Web使用webpack構(gòu)建前端項(xiàng)目
本篇文章主要介紹了詳解Web使用webpack構(gòu)建前端項(xiàng)目,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
JavaScript棧和隊(duì)列相關(guān)操作與實(shí)現(xiàn)方法詳解
這篇文章主要介紹了JavaScript棧和隊(duì)列相關(guān)操作與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了javascript棧和隊(duì)列的概念、原理、定義、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-12-12
HTML+JS實(shí)現(xiàn)經(jīng)典推箱子游戲
今天,這篇文章將利用HTML,CSS,JS的知識(shí)編寫一個(gè)童年經(jīng)典游戲?-?推箱子,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-11-11

