uni-app使用uniCloud實(shí)現(xiàn)圖形驗(yàn)證碼(uni-captcha)詳細(xì)過(guò)程
前言
uniCloud 是 DCloud 聯(lián)合阿里云、騰訊云,為開(kāi)發(fā)者提供的基于 serverless 模式和 js 編程的云開(kāi)發(fā)平臺(tái)。
- 官方文檔:https://uniapp.dcloud.net.cn/uniCloud/uni-captcha.html
- 下載地址:https://ext.dcloud.net.cn/plugin?id=4048
- GitCode 倉(cāng)庫(kù):https://gitee.com/dcloud/uni-captcha
圖形驗(yàn)證碼主要起到人機(jī)校驗(yàn)或其他限制調(diào)用的作用,如:
- 防止機(jī)器冒充人類(lèi)做暴力破解
- 防止大規(guī)模在線注冊(cè)濫用服務(wù)
- 防止濫用在線批量操作
- 防止信息被大量采集聚合
常見(jiàn)的業(yè)務(wù)場(chǎng)景有:
- 注冊(cè)環(huán)節(jié):防止無(wú)效垃圾注冊(cè),從源頭進(jìn)行管理
- 登錄環(huán)節(jié):防止撞庫(kù)攻擊、暴力破解,保障用戶數(shù)據(jù)
- 短信防刷:減少短信接口被刷情況,減少企業(yè)不必要成本
- 互動(dòng)環(huán)節(jié):防止批量垃圾互動(dòng)信息,破壞用戶UGC內(nèi)容生態(tài)
- 激勵(lì)領(lǐng)取:防止被批量褥羊毛
組成部分
- 數(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ù)端請(qǐng)求某一應(yīng)用場(chǎng)景的驗(yàn)證碼。提示:這里用場(chǎng)景值scene,表示應(yīng)用場(chǎ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和場(chǎng)景值的舊驗(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方法詳情,也可以直接查庫(kù)校驗(yàn)。
一、創(chuàng)建Demo
首先我們創(chuàng)建一個(gè)uni-app的demo,來(lái)演示功能效果。首先打開(kāi)HBuilderX,選擇:文件->新建->項(xiàng)目->uni-app,選擇模板uni-ui項(xiàng)目,如下圖:
二、創(chuàng)建云函數(shù)
Demo創(chuàng)建好后,我們來(lái)創(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登錄頁(yè)
demo和云函數(shù)都創(chuàng)建成功后,我們實(shí)現(xiàn)一個(gè)簡(jiǎn)單的登錄頁(yè)面,如下圖:
這里我們使用普通驗(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="請(qǐng)輸入姓名" /> </uni-forms-item> <uni-forms-item required label="密碼" name="password"> <uni-easyinput type="password" v-model="formData.password" placeholder="請(qǐng)輸入姓名" /> </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 需要通過(guò) 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: '請(qǐng)輸入姓名' } ] }, password: { rules: [ { required: true, errorMessage: '請(qǐng)輸入密碼' } ] }, captcha: { rules: [ { required: true, errorMessage: '請(qǐng)輸入驗(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)擊“登錄”按鈕,如果未填寫(xiě)任務(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ù)庫(kù)對(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)不通過(guò) 執(zhí)行 reject(new Error('錯(cuò)誤信息')) 返回對(duì)應(yīng)的錯(cuò)誤信息,如果校驗(yàn)通過(guò)則直接執(zhí)行 resolve() 即可,在異步校驗(yàn)方法中,不需要使用 callback 。
首先我們?cè)诘卿涰?yè)引入云對(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: '請(qǐng)輸入驗(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),所有信息都填寫(xiě)后,點(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ò)展庫(kù)依賴“
。
選擇”uni-captcha“公共模板,點(diǎn)擊確認(rèn)。然后再次右擊uni-captcha-demo選擇”上傳部署“即可。
以上步驟完成后,我們?cè)俅螌Ⅱ?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ù),如果覺(jué)得此組件不好用,也可以自己使用uni-captcha-co獲取驗(yàn)證進(jìn)行個(gè)性化操作。
這里主要是為了演示,就先在原基本上完成刷新功能。打開(kāi)uni_modules目錄,找到uni-captcha組件,再打開(kāi)components目錄中的uni-captcha,我們來(lái)看下內(nèi)部是如何實(shí)現(xiàn)的。
如上圖所示,我們發(fā)現(xiàn)應(yīng)用場(chǎ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: '請(qǐng)輸入驗(yàn)證碼' }, { validateFunction: (rule, value, data, callback) => { return new Promise((resolve, reject) => { uniCaptchaDemoCo.verify(this.formData).then(e=>{ resolve(); }).catch(e => { //修改場(chǎng)景值,重新獲取驗(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)證碼接口,這里不使用組件模塊,直接通過(guò)接口獲取驗(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ù)庫(kù)對(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、場(chǎng)景值、狀態(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í)說(shuō)明:此處配置 > uni-config-center return await uniCaptcha[action]({ scene, //來(lái)源客戶端傳遞,表示:使用場(chǎng)景值,用于防止不同功能的驗(yàn)證碼混用 uniPlatform: platform }) } }
將前面登錄頁(yè)面引入的云對(duì)象更換成“uni-captcha-co”,然后定義getVerifyImage()函數(shù),獲取圖形驗(yàn)證碼。
公共模塊中提供了刷新驗(yàn)證碼功能,測(cè)試發(fā)現(xiàn)設(shè)備校驗(yàn)這塊,本地模擬測(cè)試存在問(wèn)題,所以這里未使用,有需要的可以自行研究。
頁(yè)面代碼如下:
<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="請(qǐng)輸入姓名" /> </uni-forms-item> <uni-forms-item required label="密碼" name="password"> <uni-easyinput type="password" v-model="formData.password" placeholder="請(qǐng)輸入姓名" /> </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="請(qǐng)輸入驗(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: '請(qǐng)輸入姓名' } ] }, password: { rules: [ { required: true, errorMessage: '請(qǐng)輸入密碼' } ] }, captcha: { rules: [ { required: true, errorMessage: '請(qǐng)輸入驗(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í),頁(yè)面布局可以根據(jù)需求來(lái)實(shí)現(xiàn)圖形驗(yàn)證,頁(yè)面效果圖下:
7.2校驗(yàn)驗(yàn)證碼
把校驗(yàn)驗(yàn)證碼功能函數(shù)拷到uni-captcha-co/index.obj.js中,代碼如下:
// 開(kāi)發(fā)文檔: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj //導(dǎo)入驗(yàn)證碼公共模塊 const uniCaptcha = require('uni-captcha') //獲取數(shù)據(jù)庫(kù)對(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: '請(qǐng)輸入驗(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)的一個(gè)比較不錯(cuò)的判斷節(jié)假日的實(shí)現(xiàn)代碼(假日包括周末,不包括調(diào)休上班的周末)
最近需要實(shí)現(xiàn)一個(gè)判斷今天是不是節(jié)假日的功能,考慮周末與法定節(jié)假日調(diào)休等,這樣的比較完整的功能就需要下面的代碼來(lái)實(shí)現(xiàn)了2024-05-05JS繼承實(shí)現(xiàn)方法及優(yōu)缺點(diǎn)詳解
這篇文章主要介紹了JS繼承實(shí)現(xiàn)方法及優(yōu)缺點(diǎn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09JS+canvas實(shí)現(xiàn)的五子棋游戲【人機(jī)大戰(zhàn)版】
這篇文章主要介紹了JS+canvas實(shí)現(xiàn)的五子棋游戲,是采用比較強(qiáng)的AI實(shí)現(xiàn)的人機(jī)大戰(zhàn)版游戲,涉及javascript結(jié)合HTML5實(shí)現(xiàn)圖形繪制與人工智能相關(guān)操作技巧,需要的朋友可以參考下2017-07-07cocos2dx骨骼動(dòng)畫(huà)Armature源碼剖析(一)
cocos2dx中的骨骼動(dòng)畫(huà)在程序中使用非常方便,從編輯器(cocostudio或flash插件dragonBones)得到xml或json數(shù)據(jù),調(diào)用代碼就可以直接展示出動(dòng)畫(huà)效果,下面通過(guò)本篇文章給大家分享cocos2dx骨骼動(dòng)畫(huà)Armature源碼剖析,需要的朋友一起來(lái)學(xué)習(xí)吧。2015-09-09用js實(shí)現(xiàn)的一個(gè)根據(jù)內(nèi)容自動(dòng)生成表格的函數(shù)
用js實(shí)現(xiàn)的一個(gè)根據(jù)內(nèi)容自動(dòng)生成表格的函數(shù)...2007-08-08js多級(jí)樹(shù)形彈出一個(gè)小窗口層(非常好用)實(shí)例代碼
js多級(jí)樹(shù)形彈出一個(gè)小窗口層(非常好用)實(shí)例代碼,需要的朋友可以參考一下2013-03-03JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實(shí)例
這篇文章主要介紹了JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實(shí)例,本文先是講解了聲明數(shù)組的方法,然后對(duì)4個(gè)函數(shù)使用給出了一些例子,需要的朋友可以參考下2014-08-08