目錄
用途說(shuō)明
組成部分
目錄結(jié)構(gòu)
原理時(shí)序
云端一體組件介紹
驗(yàn)證碼配置(可選):
普通驗(yàn)證碼組件
公共模塊
云函數(shù)公用模塊
項(xiàng)目實(shí)戰(zhàn)?
創(chuàng)建云函數(shù)
創(chuàng)建注冊(cè)頁(yè)?
創(chuàng)建云函數(shù)
關(guān)聯(lián)公用模塊?uni-captcha
刷新驗(yàn)證碼
?自定義實(shí)現(xiàn) 驗(yàn)證碼
獲取驗(yàn)證碼
刷新驗(yàn)證碼
校驗(yàn)驗(yàn)證碼
下載地址:uni-captcha - DCloud 插件市場(chǎng)
GitCode 倉(cāng)庫(kù):uniCaptcha: 基于uniCloud的驗(yàn)證碼模塊
用途說(shuō)明
主要起到人機(jī)校驗(yàn)或其他限制調(diào)用的作用,如:
- 防止機(jī)器冒充人類做暴力破解
- 防止大規(guī)模在線注冊(cè)濫用服務(wù)
- 防止濫用在線批量操作
- 防止信息被大量采集聚合
常見的業(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)?。悍乐贡慌咳煅蛎?/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)證碼
目錄結(jié)構(gòu)
?
原理時(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)。
以上即完整的流程。 如果在前端表單頁(yè)面中,使用本插件封裝好的云端一體組件,并配置組件的屬性場(chǎng)景值scene
,即等價(jià)于如上步驟1-3;
本插件已集成使用示例,使用HBuilderX導(dǎo)入示例項(xiàng)目體驗(yàn);另外你也可以參考插件在uni-starter中的應(yīng)用
云端一體組件介紹
內(nèi)置調(diào)用uni-captcha-co
云對(duì)象集成創(chuàng)建/刷新驗(yàn)證碼,組件支持雙向數(shù)據(jù)綁定。
驗(yàn)證碼配置(可選):
參數(shù)說(shuō)明:
字段 | 類型 | 默認(rèn)值 | 說(shuō)明 |
---|---|---|---|
width | Number | 150 | 圖片寬度 |
height | Number | 40 | 圖片高度 |
background | String | #FFFAE8 | 驗(yàn)證碼背景色,設(shè)置空字符'' 不使用背景顏色 |
size | Number | 4 | 驗(yàn)證碼長(zhǎng)度,最多 6 個(gè)字符 |
noise | Number | 4 | 驗(yàn)證碼干擾線條數(shù) |
color | Boolean | false | 字體是否使用隨機(jī)顏色,當(dāng)設(shè)置background 后恒為true
|
fontSize | Number | 40 | 字體大小 |
ignoreChars | String | 忽略哪些字符 | |
mathExpr | Boolean | false | 是否使用數(shù)學(xué)表達(dá)式 |
mathMin | Number | 1 | 表達(dá)式所使用的最小數(shù)字 |
mathMax | Number | 9 | 表達(dá)式所使用的最大數(shù)字 |
mathOperator | String | 表達(dá)式所使用的運(yùn)算符,支持?+ 、- 。不傳則隨機(jī)使用 |
|
expiresDate | Number | 180 | 驗(yàn)證碼過期時(shí)間(s) |
scene | Object | 根據(jù)場(chǎng)景值配置(版本號(hào):0.6.0+ 支持) |
普通驗(yàn)證碼組件
組件名:uni-captcha
組件遵從easycom組件規(guī)范
使用示例:
<template>
<uni-captcha scene="場(chǎng)景值" v-model="驗(yàn)證碼的值"></uni-captcha>
</template>
Props:
字段 | 類型 | 必填 | 默認(rèn)值 | 說(shuō)明 |
---|---|---|---|---|
scene | String | 是 | - | 使用場(chǎng)景值,用于防止不同功能的驗(yàn)證碼混用,如:login 、pay
|
value/v-model | String | - | - | 驗(yàn)證碼的值 |
公共模塊
- 云端一體組件
uni-captcha
和uni-popup-captcha
,已經(jīng)集成公共模塊的獲取驗(yàn)證碼create
和刷新驗(yàn)證碼refresh
接口。 - 引入公共模塊請(qǐng)參考云函數(shù)公用模塊
云函數(shù)公用模塊
云函數(shù)支持公共模塊。多個(gè)云函數(shù)的共享部分,可以抽離為公共模塊,然后被多個(gè)云函數(shù)引用。
版本要求:HBuilderX 2.6.6+
以下面的目錄結(jié)構(gòu)為例,介紹一下如何使用。
?
?新建并引入公用模塊
- 在
cloudfunctions
目錄下創(chuàng)建common
目錄 - 在
common
目錄右鍵創(chuàng)建公用模塊目錄(本例中為hello-common
,見下方示例圖),會(huì)自動(dòng)創(chuàng)建入口index.js
文件和package.json
,不要修改此package.json的name字段 - 在
hello-common
右鍵上傳公用模塊 - 在云函數(shù)上右鍵選擇
管理公共模塊依賴
,添加依賴的公共模塊
?
公共模塊依賴其他公共模塊同理
注意事項(xiàng)
- 如果要更新所有依賴某公用模塊的云函數(shù),可以在
common
目錄下的公用模塊目錄(本例中為hello-common
)右鍵選擇更新依賴本模塊的云函數(shù)
- 公用模塊命名不可與nodejs內(nèi)置模塊重名
- 從插件市場(chǎng)導(dǎo)入或者其他地方復(fù)制項(xiàng)目可能會(huì)導(dǎo)致
npm install
創(chuàng)建的軟鏈接失效,如果遇到這種情況請(qǐng)刪除node_modules
和package-lock.json
重新npm install
?
使用公用模塊
仍以上面的目錄為例,在公用模塊內(nèi)exports
,在云函數(shù)內(nèi)require
即可。示例代碼如下:
// common/hello-common/index.js
function getVersion() {
return '0.0.1'
}
module.exports = {
getVersion,
secret: 'your secret'
}
// use-common/index.js
'use strict';
const {
secret,
getVersion
} = require('hello-common')
exports.main = async (event, context) => {
let version = getVersion()
return {
secret,
version
}
}
項(xiàng)目實(shí)戰(zhàn)?
創(chuàng)建云函數(shù)
我們來(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è)模塊。
??
創(chuàng)建注冊(cè)頁(yè)?
云函數(shù)都創(chuàng)建成功后,我們實(shí)現(xiàn)一個(gè)簡(jiǎn)單的登錄頁(yè)面,如下圖:
博主 from表單使用了? uview 可以換成 uni-ui
uView - 多平臺(tái)快速開發(fā)的UI框架 - uni-app UI框架
<template>
<view class="container">
<view class="wrapper">
<view class="title">
用戶注冊(cè)
</view>
<view class="input-content">
<u-form :model="form" ref="uForm">
<u-form-item label="手機(jī)" prop="Phone">
<u-input placeholder="請(qǐng)輸入手機(jī)號(hào)" v-model="form.Phone" />
</u-form-item>
<u-form-item label="密碼" prop="Password">
<u-input type="password" placeholder="請(qǐng)輸入密碼" v-model="form.Password" />
</u-form-item>
<u-form-item label="密碼" prop="Password1">
<u-input type="password" placeholder="確認(rèn)密碼" v-model="form.Password1" />
</u-form-item>
<u-form-item prop="captcha" label="驗(yàn)證碼" label-width="100rpx">
<uni-captcha :scene="form.scene" v-model="form.captcha"></uni-captcha>
</u-form-item>
</u-form>
</view>
<button class="confirm-btn" @click="register()">注冊(cè)</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
// 校驗(yàn)規(guī)則
rules: {
Phone: [{
required: true,
message: '請(qǐng)輸入手機(jī)號(hào)',
// 可以單個(gè)或者同時(shí)寫兩個(gè)觸發(fā)驗(yàn)證方式
trigger: ['change', 'blur'],
},
{
// 自定義驗(yàn)證函數(shù),見上說(shuō)明
validator: (rule, value, callback) => {
// 上面有說(shuō),返回true表示校驗(yàn)通過,返回false表示不通過
// this.$u.test.mobile()就是返回true或者false的
return this.$u.test.mobile(value);
},
message: '手機(jī)號(hào)碼不正確',
// 觸發(fā)器可以同時(shí)用blur和change
trigger: ['change', 'blur'],
}
],
Password: [{
required: true,
message: '請(qǐng)輸入密碼',
// 可以單個(gè)或者同時(shí)寫兩個(gè)觸發(fā)驗(yàn)證方式
trigger: ['change', 'blur'],
},
{
min: 6,
message: '密碼不能少于5個(gè)字',
trigger: 'change'
}
],
Password1: [{
required: true,
message: '請(qǐng)輸入確認(rèn)密碼',
// 可以單個(gè)或者同時(shí)寫兩個(gè)觸發(fā)驗(yàn)證方式
trigger: ['change', 'blur'],
},
{
// 自定義驗(yàn)證函數(shù),見上說(shuō)明
validator: (rule, value, callback) => {
// 上面有說(shuō),返回true表示校驗(yàn)通過,返回false表示不通過
// this.$u.test.mobile()就是返回true或者false的
return value === this.form.Password
},
message: '兩次密碼不一致',
// 觸發(fā)器可以同時(shí)用blur和change
trigger: ['change', 'blur'],
}
],
captcha: [{
required: true,
message: '請(qǐng)輸入驗(yàn)證碼',
// 可以單個(gè)或者同時(shí)寫兩個(gè)觸發(fā)驗(yàn)證方式
trigger: ['change', 'blur'],
}]
},
form: {
Phone: '',
Password: '',
Password1: '',
scene: "register",
captcha: ""
},
}
},
// 必須要在onReady生命周期,因?yàn)閛nLoad生命周期組件可能尚未創(chuàng)建完畢
onReady() {
console.log("執(zhí)行");
this.$refs.uForm.setRules(this.rules);
},
methods: {
register() {
this.$refs.uForm.validate(valid => {
if (valid) {
let data = {
...this.form
}
uniCloud.callFunction({
name: "register",
data: data
}).then(res => {
console.log(res);
if (res.result.code == 0) {
this.$u.toast('注冊(cè)成功');
setTimeout(() => {
uni.navigateBack()
}, 300)
} else {
this.form['scene'] = 'register' + Math.random();
this.$u.toast(res.result.message);
}
})
} else {
console.log('驗(yàn)證失敗');
}
});
}
},
}
</script>
/* <style lang='scss'>
.container {
padding-top: 50px;
width: 100vw;
height: 100vh;
background: #fff;
}
.wrapper {
background: #fff;
padding-bottom: 40upx;
}
.title {
text-align: center;
margin-bottom: 100rpx;
font-size: 46upx;
color: #555;
text-shadow: 1px 0px 1px rgba(0, 0, 0, .3);
}
.input-content {
padding: 0 60upx;
}
.input-item {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 0 30upx;
background: $page-color-light;
height: 120upx;
border-radius: 4px;
margin-bottom: 50upx;
&:last-child {
margin-bottom: 0;
}
.tit {
height: 50upx;
line-height: 56upx;
font-size: $font-sm+2upx;
color: $font-color-base;
}
input {
height: 60upx;
font-size: $font-base + 2upx;
color: $font-color-dark;
width: 100%;
}
}
.confirm-btn {
width: 630upx;
height: 76upx;
line-height: 76upx;
border-radius: 50px;
margin-top: 70upx;
background: $uni-theme-color;
color: #fff;
font-size: $font-lg;
&:after {
border-radius: 100px;
}
}
.forget-section {
font-size: $font-sm+2upx;
color: $uni-theme-color;
text-align: center;
margin-top: 40upx;
}
.captcha_box {
.input {}
.captcha {
width: 240rpx;
height: 72rpx;
}
}
</style>
創(chuàng)建云函數(shù)
此時(shí)我們創(chuàng)建一個(gè)云函數(shù),用于對(duì)表單中輸入的驗(yàn)證碼,進(jìn)行校驗(yàn)其是否正確。還是在cloudfunctions上右擊,選擇“新建云函數(shù)/云對(duì)象”,如下圖:
?
?點(diǎn)擊創(chuàng)建后,cloudfunctions中會(huì)生成云函數(shù)。如下圖:
??
?此時(shí)可以在index.js中添加圖形驗(yàn)證碼校驗(yàn)功能,返回校驗(yàn)結(jié)果。代碼如下:
'use strict';
//導(dǎo)入驗(yàn)證碼公共模塊
const uniCaptcha = require('uni-captcha')
const db = uniCloud.database();
exports.main = async (event) => {
const { Phone, Password, scene, captcha } = event;
try {
// 校驗(yàn)驗(yàn)證碼
let res = await uniCaptcha.verify({ scene, captcha })
// 驗(yàn)證通過
if (res.code == 0) {
// 校驗(yàn)是否已經(jīng)注冊(cè)
const userExists = await db.collection("User").where({ Phone: Phone }).get();
if (userExists.data.length !== 0) {
return {
code: 1,
message: "該賬號(hào)已注冊(cè)",
};
}
// 添加用戶
await db.collection("User").add({
time: Date.now(),
Phone: Phone,
Password: Password,
});
return {
code: 0,
message: "注冊(cè)成功"
};
} else {
// 驗(yàn)證失敗
return {
code: -1,
message: res.errMsg || res.message || "驗(yàn)證碼異常",
};
}
} catch (error) {
// 出現(xiàn)異常
console.error('添加用戶失敗:', error);
return {
code: -1,
message: "注冊(cè)失敗,請(qǐng)稍后重試",
};
}
};
關(guān)聯(lián)公用模塊?uni-captcha
在云函數(shù)上鼠標(biāo)右擊,選擇”管理公共模塊或擴(kuò)展庫(kù)依賴“
選擇”uni-captcha“公共模板,點(diǎn)擊確認(rèn)。
刷新驗(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,我們來(lái)看下內(nèi)部是如何實(shí)現(xiàn)的。
如上圖所示,我們發(fā)現(xiàn)應(yīng)用場(chǎng)景發(fā)生改變后,驗(yàn)證碼會(huì)重新獲取。所以上文中這樣做的
加入隨機(jī)數(shù)讓其變化
?
?自定義實(shí)現(xiàn) 驗(yàn)證碼
獲取驗(yàn)證碼
用于新的驗(yàn)證碼記錄(使用云端一體組件的用戶可以忽略)
//引入公共模塊
const uniCaptcha = require('uni-captcha')
module.exports = {
async createCaptcha({scene}) {
return await uniCaptcha.create({
scene,
width:100,
height:44
});
}
}
參數(shù)說(shuō)明
字段 | 類型 | 必填 | 默認(rèn)值 | 說(shuō)明 |
---|---|---|---|---|
scene | String | 是 | - | 使用場(chǎng)景值,用于防止不同功能的驗(yàn)證碼混用,如:login 、pay
|
deviceId | String | - | - | 設(shè)備 id,如果不傳,將自動(dòng)從 uniCloud 上下文獲取 |
uniPlatform | String | - | - | uni-app 運(yùn)行平臺(tái) |
width | Number | - | 150 | 圖片寬度 |
height | Number | - | 40 | 圖片高度 |
background | String | - | #FFFAE8 | 驗(yàn)證碼背景色,設(shè)置空字符'' 不使用背景顏色 |
size | Number | - | 4 | 驗(yàn)證碼長(zhǎng)度,最多 6 個(gè)字符 |
noise | Number | - | 4 | 驗(yàn)證碼干擾線條數(shù) |
color | Boolean | - | false | 字體是否使用隨機(jī)顏色,當(dāng)設(shè)置background 后恒為true
|
fontSize | Number | - | 40 | 字體大小 |
ignoreChars | String | - | '' | 忽略哪些字符 |
mathExpr | Boolean | - | false | 是否使用數(shù)學(xué)表達(dá)式 |
mathMin | Number | - | 1 | 表達(dá)式所使用的最小數(shù)字 |
mathMax | Number | - | 9 | 表達(dá)式所使用的最大數(shù)字 |
mathOperator | String | - | '' | 表達(dá)式所使用的運(yùn)算符,支持?+ 、- 。不傳則隨機(jī)使用 |
expiresDate | Number | - | 180 | 驗(yàn)證碼過期時(shí)間(s) |
注意:
- 自
uni-captcha 0.3.0
起,支持在unicloud配置中心uni-config-center
->uni-captcha
->config.json
中配置參數(shù)默認(rèn)值 - 如果想替換字體,請(qǐng)保證字體格式為?
.ttf
?且包含?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-
?字符
響應(yīng)參數(shù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-797920.html
字段 | 類型 | 說(shuō)明 |
---|---|---|
errCode | Number | 錯(cuò)誤碼,0 表示成功 |
errMsg | String | 詳細(xì)信息 |
captchaBase64 | String | 驗(yàn)證碼:base64 格式 |
刷新驗(yàn)證碼
作廢相同設(shè)備id和場(chǎng)景值的驗(yàn)證碼記錄,并創(chuàng)建新的驗(yàn)證碼記錄(使用云端一體組件的用戶可以忽略)
//引入公共模塊
const uniCaptcha = require('uni-captcha')
const db = uniCloud.database();
const verifyCodes = db.collection('opendb-verify-codes')
module.exports = {
async refreshCaptcha({scene}) {
let res = await verifyCodes.where({scene,deviceId,state:0}).limit(1).get()
if(res.data.length){
return await uniCaptcha.refresh({
scene,
width:100,
height:44
});
}else{
return {
errCode: "uni-captcha-refresh-fail",
errMsg: '未找到相同設(shè)備id和場(chǎng)景值的有效驗(yàn)證碼記錄'
}
}
}
}
參數(shù)說(shuō)明
字段 | 類型 | 必填 | 默認(rèn)值 | 說(shuō)明 |
---|---|---|---|---|
scene | String | 是 | - | 類型,用于防止不同功能的驗(yàn)證碼混用 |
deviceId | String | - | - | 設(shè)備 id,如果不傳,將自動(dòng)從 uniCloud 上下文獲取 |
響應(yīng)參數(shù)
字段 | 類型 | 說(shuō)明 |
---|---|---|
errCode | Number | 錯(cuò)誤碼,0 表示成功 |
errMsg | String | 詳細(xì)信息 |
captchaBase64 | String | 驗(yàn)證碼:base64 格式 |
注意:
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-797920.html
- 支持傳入 create 方法的所有參數(shù),如果不傳,則自動(dòng)按照 deviceId 匹配上次生成時(shí)的配置生成新的驗(yàn)證碼
校驗(yàn)驗(yàn)證碼
用于驗(yàn)證用戶輸入的驗(yàn)證碼是否正確
const uniCaptcha = require('uni-captcha')
module.exports = {
async verify({scene,captcha}) {
let res = await uniCaptcha.verify({scene,captcha})
if(res.code == 0){
//...這里寫你的業(yè)務(wù)邏輯
}else{
return res
}
}
}
參數(shù)說(shuō)明
字段 | 類型 | 必填 | 默認(rèn)值 | 說(shuō)明 |
---|---|---|---|---|
scene | String | 是 | - | 類型,用于防止不同功能的驗(yàn)證碼混用 |
captcha | String | 是 | - | 驗(yàn)證碼 |
deviceId | String | - | - | 設(shè)備 id,如果不傳,將自動(dòng)從 uniCloud 上下文獲取 |
響應(yīng)參數(shù)
字段 | 類型 | 說(shuō)明 |
---|---|---|
errCode | Number | 錯(cuò)誤碼,0 表示成功 |
errMsg | String | 詳細(xì)信息 |
注意:
- 若提示驗(yàn)證碼失效,請(qǐng)重新獲取
- 如果為了更小的代碼體積,不想使用本方法,也可以直接查庫(kù)校驗(yàn)
到了這里,關(guān)于uniCloud ---- uni-captch實(shí)現(xiàn)圖形驗(yàn)證碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!