提交 4e3ad9cf 编写于 作者: DCloud_JSON's avatar DCloud_JSON 提交者: study夏羽

修复在某些情况下,微信小程序端验证码显示错误的问题

上级 3f513e3a
## 1.2.1(2022-05-18)
- 修复在某些情况下,微信小程序端验证码显示错误的问题
## 1.2.0(2022-05-16) ## 1.2.0(2022-05-16)
- 短信验证码登陆、绑定手机号码新增防刷逻辑。当短信验证码输入错误2次以上,弹出图形验证码进行人机校验。 - 短信验证码登陆、绑定手机号码新增防刷逻辑。当短信验证码输入错误2次以上,弹出图形验证码进行人机校验。
- uni-id-cf,新增防刷机制。更改loginLog为uniIdLog 记录各类uni-id操作,并新增action字段记录操作的行为名称 - uni-id-cf,新增防刷机制。更改loginLog为uniIdLog 记录各类uni-id操作,并新增action字段记录操作的行为名称
......
{ {
"name": "uni-starter", "name" : "uni-starter-old",
"appid": "请点击重新获取", "appid" : "__UNI__EC87F46",
"description": "云端一体应用快速开发模版", "description" : "云端一体应用快速开发模版",
"versionName": "1.0.0", "versionName" : "1.0.0",
"versionCode": "100", "versionCode" : "100",
"transformPx": false, "transformPx" : false,
"app-plus": { "app-plus" : {
"locales": { "locales" : {
"en": { "en" : {
"name": "uni-starter", "name" : "uni-starter",
"android": { "android" : {
"strings": { "strings" : {
"CustomKey": "CustomValue" "CustomKey" : "CustomValue"
} }
},
"ios" : {
"privacyDescription" : {
"NSPhotoLibraryUsageDescription" : "access to the user’s photo library(read)"
},
"infoPlist" : {
"CustomKey" : "CustomValue"
}
}
},
"zh" : {
"name" : "统一应用基本项目"
}
}, },
"ios": { "privacy" : {
"privacyDescription": { "prompt" : "template",
"NSPhotoLibraryUsageDescription": "access to the user’s photo library(read)" "template" : {
}, "title" : "服务协议和隐私政策",
"infoPlist": { "message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://ask.dcloud.net.cn/protocol.html\">《服务协议》</a>和<a href=\"https://ask.dcloud.net.cn/protocol.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"CustomKey": "CustomValue" "buttonAccept" : "同意",
} "buttonRefuse" : "暂不同意"
} }
},
"zh": {
"name": "统一应用基本项目"
}
},
"privacy": {
"prompt": "template",
"template": {
"title": "服务协议和隐私政策",
"message": "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://ask.dcloud.net.cn/protocol.html\">《服务协议》</a>和<a href=\"https://ask.dcloud.net.cn/protocol.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意",
"buttonRefuse": "暂不同意"
}
},
"compatible": {
"ignoreVersion": true
},
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": false,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {
"Fingerprint": {
},
"Share": {
},
"OAuth": {
},
"FaceID": {
},
"Geolocation": {
},
"Bluetooth": {
},
"Push": {
},
"Maps": {
}
},
"distribute": {
"android": {
"permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters": [
"armeabi-v7a",
"arm64-v8a",
"x86"
]
},
"ios": {
"capabilities": {
"entitlements": {
"com.apple.developer.associated-domains": [
"applinks:static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com"
]
}
}
},
"sdkConfigs": {
"oauth": {
"apple": {
},
"weixin": {
"appid": "",
"appsecret": "",
"UniversalLinks": ""
},
"univerify": {
}
}, },
"ad": { "compatible" : {
"ignoreVersion" : true
}, },
"share": { "usingComponents" : true,
"weixin": { "nvueStyleCompiler" : "uni-app",
"appid": "", "compilerVersion" : 3,
"UniversalLinks": "" "splashscreen" : {
} "alwaysShowBeforeRender" : false,
"waiting" : true,
"autoclose" : true,
"delay" : 0
}, },
"geolocation": { "modules" : {
"baidu": { "Fingerprint" : {},
"__platform__": [ "Share" : {},
"ios", "OAuth" : {},
"android" "FaceID" : {},
], "Geolocation" : {},
"appkey_ios": "请填写地图的key", "Bluetooth" : {},
"appkey_android": "请填写地图的key" "Push" : {},
} "Maps" : {}
}, },
"push": { "distribute" : {
"unipush": { "android" : {
"version": "2", "permissions" : [
"offline": true, "<uses-feature android:name=\"android.hardware.camera\"/>",
"meizu": { "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.USE_FINGERPRINT\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
}, },
"mi": { "ios" : {
"capabilities" : {
"entitlements" : {
"com.apple.developer.associated-domains" : [ "applinks:static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com" ]
}
}
}, },
"vivo": { "sdkConfigs" : {
"oauth" : {
"apple" : {},
"weixin" : {
"appid" : "",
"appsecret" : "",
"UniversalLinks" : ""
},
"univerify" : {}
},
"ad" : {},
"share" : {
"weixin" : {
"appid" : "",
"UniversalLinks" : ""
}
},
"geolocation" : {
"baidu" : {
"__platform__" : [ "ios", "android" ],
"appkey_ios" : "请填写地图的key",
"appkey_android" : "请填写地图的key"
}
},
"push" : {
"unipush" : {
"version" : "2",
"offline" : true,
"meizu" : {},
"mi" : {},
"vivo" : {},
"oppo" : {},
"hms" : {}
}
},
"payment" : {},
"maps" : {}
}, },
"oppo": { "icons" : {
"android" : {
"hdpi" : "",
"xhdpi" : "",
"xxhdpi" : "",
"xxxhdpi" : ""
},
"ios" : {
"appstore" : "",
"ipad" : {
"app" : "",
"app@2x" : "",
"notification" : "",
"notification@2x" : "",
"proapp@2x" : "",
"settings" : "",
"settings@2x" : "",
"spotlight" : "",
"spotlight@2x" : ""
},
"iphone" : {
"app@2x" : "",
"app@3x" : "",
"notification@2x" : "",
"notification@3x" : "",
"settings@2x" : "",
"settings@3x" : "",
"spotlight@2x" : "",
"spotlight@3x" : ""
}
}
}, },
"hms": { "splashscreen" : {
"iosStyle" : "common",
"androidStyle" : "common",
"useOriginalMsgbox" : true
} }
}
},
"payment": {
}, },
"maps": { "nvueLaunchMode" : ""
} },
}, "quickapp" : {},
"icons": { "mp-weixin" : {
"android": { "appid" : "",
"hdpi": "", "setting" : {
"xhdpi": "", "urlCheck" : false,
"xxhdpi": "", "es6" : false
"xxxhdpi": ""
}, },
"ios": { "usingComponents" : true,
"appstore": "", "betterScopedSlots" : true,
"ipad": { "permission" : {
"app": "", "scope.userLocation" : {
"app@2x": "", "desc" : "演示在onShow生命周期获取地理位置"
"notification": "", }
"notification@2x": "",
"proapp@2x": "",
"settings": "",
"settings@2x": "",
"spotlight": "",
"spotlight@2x": ""
},
"iphone": {
"app@2x": "",
"app@3x": "",
"notification@2x": "",
"notification@3x": "",
"settings@2x": "",
"settings@3x": "",
"spotlight@2x": "",
"spotlight@3x": ""
}
} }
},
"splashscreen": {
"iosStyle": "common",
"androidStyle": "common",
"useOriginalMsgbox": true
}
}, },
"nvueLaunchMode": "" "mp-alipay" : {
}, "usingComponents" : true
"quickapp": {
},
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false,
"es6": false
}, },
"usingComponents": true, "mp-baidu" : {
"betterScopedSlots": true, "usingComponents" : true
"permission": { },
"scope.userLocation": { "mp-toutiao" : {
"desc": "演示在onShow生命周期获取地理位置" "usingComponents" : true
}
}
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
},
"h5": {
"template": "",
"sdkConfigs": {
"maps": {
"qqmap": {
"key": ""
}
}
}, },
"router": { "uniStatistics" : {
"base": "" "enable" : false
},
"h5" : {
"template" : "",
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : ""
}
}
},
"router" : {
"base" : ""
},
"uniStatistics" : {
"enable" : true
}
}, },
"uniStatistics": { "_spaceID" : "",
"enable": true "vueVersion" : "2"
}
},
"_spaceID": "",
"vueVersion": "2"
} }
{ {
"id": "uni-starter", "id": "uni-starter",
"displayName": "uni-starter", "displayName": "uni-starter",
"version": "1.2.0", "version": "1.2.1",
"description": "云端一体应用快速开发基本项目模版", "description": "云端一体应用快速开发基本项目模版",
"keywords": [ "keywords": [
"login", "login",
......
...@@ -4,12 +4,8 @@ ...@@ -4,12 +4,8 @@
<text class="title">{{$t('pwdLogin.pwdLogin')}}</text> <text class="title">{{$t('pwdLogin.pwdLogin')}}</text>
<input class="input-box" :inputBorder="false" v-model="username" :placeholder="$t('pwdLogin.placeholder')"/> <input class="input-box" :inputBorder="false" v-model="username" :placeholder="$t('pwdLogin.placeholder')"/>
<input type="password" class="input-box" :inputBorder="false" v-model="password" :placeholder="$t('pwdLogin.passwordPlaceholder')"/> <input type="password" class="input-box" :inputBorder="false" v-model="password" :placeholder="$t('pwdLogin.passwordPlaceholder')"/>
<!-- <view class="captcha-box" v-if="captchaBase64">
<image class="captcha-img" @click="createCaptcha" :src="captchaBase64" mode="widthFix"></image>
<input type="text" class="input-box captcha" :inputBorder="false" v-model="captcha" :placeholder="$t('pwdLogin.verifyCodePlaceholder')"/>
</view> -->
<uni-captcha scene="login" v-model="captcha"></uni-captcha> <uni-captcha scene="login" v-model="captcha"></uni-captcha>
<uni-agreements @setAgree="agree = $event"></uni-agreements> <uni-agreements class="agreement" @setAgree="agree = $event"></uni-agreements>
<button class="send-btn" :disabled="!canLogin" :type="canLogin?'primary':'default'" <button class="send-btn" :disabled="!canLogin" :type="canLogin?'primary':'default'"
@click="pwdLogin">{{$t('pwdLogin.login')}}</button> @click="pwdLogin">{{$t('pwdLogin.login')}}</button>
<!-- 忘记密码 --> <!-- 忘记密码 -->
......
## 0.5.1(2022-05-18)
- 修复在某些情况下微信小程序端验证码显示错误的问题
## 0.5.0(2022-05-17)
- 新增支持在`uni-captcha-co`->`config`配置验证码
## 0.4.1(2022-05-16) ## 0.4.1(2022-05-16)
- 新增示例项目 - 新增示例项目
## 0.4.0(2022-05-16) ## 0.4.0(2022-05-16)
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
uniIdCo.getImageCaptcha({ uniIdCo.getImageCaptcha({
scene: this.scene scene: this.scene
}).then(result => { }).then(result => {
console.log(result); // console.log(result);
this.captchaBase64 = result.captchaBase64 this.captchaBase64 = result.captchaBase64
}) })
.catch(e => { .catch(e => {
...@@ -107,7 +107,6 @@ ...@@ -107,7 +107,6 @@
} }
.captcha-img-box { .captcha-img-box {
cursor: pointer;
position: relative; position: relative;
background-color: #FEFAE7; background-color: #FEFAE7;
} }
...@@ -126,8 +125,13 @@ ...@@ -126,8 +125,13 @@
.captcha-img-box, .captcha-img-box,
.captcha-img, .captcha-img,
.loding { .loding {
height: 44px !important;
width: 100px; width: 100px;
} }
.captcha-img{
cursor: pointer;
}
.loding { .loding {
z-index: 9; z-index: 9;
......
{ {
"id": "uni-captcha", "id": "uni-captcha",
"displayName": "uni-captcha", "displayName": "uni-captcha",
"version": "0.4.1", "version": "0.5.1",
"description": "简洁、高效、灵活可配置的云端验证码模块", "description": "云端一体图形验证码组件",
"keywords": [ "keywords": [
"uniCloud", "uniCloud",
"captcha", "captcha",
......
## 用途说明 <h2>
主要起到人机校验或其他限制调用的作用,如: 文档已移至 <a href="https://uniapp.dcloud.io/uniCloud/uni-captcha.html" target="_blank">uni-captcha文档</a>
- 防止机器冒充人类做暴力破解 </h2>
- 防止大规模在线注册滥用服务
- 防止滥用在线批量操
- 防止信息被大量采集聚合
常见的业务场景有:
- 注册环节:防止无效垃圾注册,从源头进行管理
- 登录环节:防止撞库攻击、暴力破解,保障用户数据案例
- 短信防刷:减少短信接口被刷情况,减少企业不必要成本
- 互动环节:防止批量垃圾互动信息破坏用户UGC内容生态
## 组成部分
- openDB数据表:[opendb-verify-codes](https://gitee.com/dcloud/opendb/blob/master/collection/opendb-verify-codes/collection.json),用于存储验证码数据。
- 集成:获取验证码、校验验证码、刷新验证码的uniCloud公共模块`uni-captcha`
- 云对象`uni-captcha-co`集成获取验证码的api,`getImageCaptcha`
- 集成创建、刷新、显示验证码的云端一体验证码组件
## 目录结构@catalogue
<pre>
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
│ └─uni-captcha
│ ├─uniCloud
│ │ ├─cloudfunctions 云函数目录
│ │ │ ├─common 公共模块目录
│ │ │ │ └─uni-captcha uni-captcha公共模块
│ │ │ └─uni-captcha-co 集成调用uni-captcha方法的云对象
│ │ └─database
│ │ ├─opendb-verify-codes.schema.json 验证码数据表
│ │ └─db_init.json 初始化数据库文件
│ └─components 组件目录
│ ├─uni-captcha
│ │ └─uni-captcha.vue 普通验证码组件
│ └─uni-popup-captcha
│ └─uni-popup-captcha.vue 弹出式验证码组件
</pre>
## 原理时序
客户端携带场景值(用于防止不同功能的验证码混用,如:`login``pay`)调用云对象`uni-captcha-co``getImageCaptcha`方法,向服务端发起获取验证码请求。
方法内部通过查询数据表`opendb-verify-codes`,判断:同一设备id、相同场景值、待验证的记录是否已存在;
- 不存在则:调用公共模块`uni-captcha``create`方法创建验证码,此时数据表会创建一条验证状态(字段名:`state`)为待验证(字段值`0`)的记录。
- 已存在则:调用公共模块`uni-captcha``refresh`方法刷新这个验证码。此时更新现存记录的验证状态(字段名:`state`)的值为已作废(字段值`2`),然后数据表也会创建一条验证状态(字段名:`state`)为待验证(字段值`0`)的记录。
并向客户端返回:格式为base64的图形验证码资源数据(响应体参数名:captchaBase64)。
客户端得到数据后,显示图形验证码,用户识别后(携带参数:场景值scene、验证码captcha)提交表单,服务端调用公共模块`uni-captcha``verify`方法验证是否正确。
补充:如果是clientDB操作,不想在扩展校验函数中依赖公共模块,还可以直接查库校验验证码。
以上即完整的流程,你如果直接使用云端一体组件,仅需配置组件的场景值属性`scene`,即可实现上述功能。
## 组件介绍
### 普通验证码组件
**组件名:uni-captcha**
云端一体组件,内置调用`uni-captcha-co`云对象创建/刷新验证码,支持双向数据绑定。
仅需传入属性`scene`:场景值即可。
组件遵从[easycom组件规范](https://uniapp.dcloud.io/component/#easycom%E7%BB%84%E4%BB%B6%E8%A7%84%E8%8C%83),使用示例:
```js
<template>
<uni-captcha scene="场景值" v-model="验证码的值"></uni-captcha>
</template>
```
#### Props:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
| ------------ | ------- | ---- | ------- | ------------------------------------------------------------ |
| scene | String | 是 | - | 使用场景值,用于防止不同功能的验证码混用,如:`login``pay` |
| value/v-model| String | - | - | 验证码的值 |
### 弹出式验证码组件
**组件名:uni-popup-captcha**
验证码实现人机校验等作用的同时,降低了用户体验。为了提升用户体验:绝大部分情况下,验证码应当是非常态的,当接口被高频调用的情况下才需要。
另外验证码会使得我们的前端界面设计变得复杂。所以弹出式验证码组件,应需而生。
#### 使用示例:
```js
<template>
<uni-popup-captcha ref="popup-captcha" @confirm="verifyCaptcha" :scene="formData.scene" v-model="formData.captcha"></uni-popup-captcha>
<button @click="openPopupCaptcha" >显示弹出式验证码</button>
</template>
<script>
export default {
data() {
return {
formData:{
captcha:"",
scene:"test"
}
}
},
methods: {
verifyCaptcha(){
const uniCaptchaCo = uniCloud.importObject("uni-captcha-co")
uniCaptchaCo.verifyCaptcha(this.formData).then(e=>{
uni.showToast({
title: e.errMsg,
icon: 'none'
});
})
},
openPopupCaptcha(){
this.$refs['popup-captcha'].open()
}
}
}
</script>
```
#### Props:
| 字段 | 类型 | 必填 | 说明 |
| ------------ | ------- | ---- | ------------------------------------------------------------ |
| scene | String | 是 | 使用场景值,用于防止不同功能的验证码混用,如:`login``pay` |
| value/v-model| String | - | 验证码的值 |
#### Events
| 字段 | 类型 | 说明 |
| ------------ | ------- |---------------- |
| confirm | Function | 点击确定按钮事件 |
## 公共模块
### 获取验证码@create
用法:`uniCaptcha.create(Object params);`
**参数说明**
| 字段 | 类型 | 必填 | 默认值 | 说明 |
| ------------ | ------- | ---- | ------- | ------------------------------------------------------------ |
| scene | String | 是 | - | 使用场景值,用于防止不同功能的验证码混用,如:`login``pay` |
| deviceId | String | - | - | 设备 id,如果不传,将自动从 uniCloud 上下文获取 |
| width | Number | - | 150 | 图片宽度 |
| height | Number | - | 40 | 图片高度 |
| background | String | - | #FFFAE8 | 验证码背景色,设置空字符`''`不使用背景颜色 |
| size | Number | - | 4 | 验证码长度,最多 6 个字符 |
| noise | Number | - | 4 | 验证码干扰线条数 |
| color | Boolean | - | false | 字体是否使用随机颜色,当设置`background`后恒为`true` |
| fontSize | Number | - | 40 | 字体大小 |
| ignoreChars | String | - | '' | 忽略那些字符 |
| mathExpr | Boolean | - | false | 是否使用数学表达式 |
| mathMin | Number | - | 1 | 表达式所使用的最小数字 |
| mathMax | Number | - | 9 | 表达式所使用的最大数字 |
| mathOperator | String | - | '' | 表达式所使用的运算符,支持 `+``-`。不传随机使用 |
| expiresDate | Number | - | 180 | 验证码过期时间(s) |
**响应参数**
| 字段 | 类型 | 说明 |
| ------------- | ------ | ------------------- |
| errCode | Number | 错误码,0 表示成功 |
| errMsg | String | 详细信息 |
| captchaBase64 | String | 验证码:base64 格式 |
`注意:`
- 重新生成后,上条验证码不作废
- 刷新验证码,上条验证码作废
- 如果想替换字体,请保证字体格式为 `.ttf` 且包含 `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-` 字符
### 校验验证码@verify
用法:`uniCaptcha.verify(Object params);`
**参数说明**
| 字段 | 类型 | 必填 | 默认值 | 说明 |
| -------- | ------ | ---- | ------ | ----------------------------------------------- |
| scene | String | 是 | - | 类型,用于防止不同功能的验证码混用 |
| captcha | String | 是 | - | 验证码 |
| deviceId | String | - | - | 设备 id,如果不传,将自动从 uniCloud 上下文获取 |
**响应参数**
| 字段 | 类型 | 说明 |
| ------- | ------ | ------------------ |
| errCode | Number | 错误码,0 表示成功 |
| errMsg | String | 详细信息 |
`注意:`
- 若提示验证码失效,请重新获取
### 刷新验证码@refresh
用法:`uniCaptcha.refresh(Object params);`
**参数说明**
| 字段 | 类型 | 必填 | 默认值 | 说明 |
| -------- | ------ | ---- | ------ | ----------------------------------------------- |
| scene | String | 是 | - | 类型,用于防止不同功能的验证码混用 |
| deviceId | String | - | - | 设备 id,如果不传,将自动从 uniCloud 上下文获取 |
**响应参数**
| 字段 | 类型 | 说明 |
| ------------- | ------ | ------------------- |
| errCode | Number | 错误码,0 表示成功 |
| errMsg | String | 详细信息 |
| captchaBase64 | String | 验证码:base64 格式 |
`注意:`
- 支持传入 create 方法的所有参数,如果不传,则自动按照 deviceId 匹配上次生成时的配置生成新的验证码
## 错误码
_详细信息请查看 message 中查看_
| 模块 | 模块码 | 错误代码 | 错误信息 |
| :----: | :----: | :------: | :---------------------: |
| 验证码 | 100 | 01 | (10001)验证码生成失败 |
| | | 02 | (10002)验证码校验失败 |
| | | 03 | (10003)验证码刷新失败 |
module.exports = {
"image-captcha":{
"width": 150, //图片宽度
"height": 44, //图片高度
"background": "#FFFAE8", //验证码背景色,设置空字符`''`不使用背景颜色
// "size": 4, //验证码长度,最多 6 个字符
// "noise": 4, //验证码干扰线条数
// "color": false, //字体是否使用随机颜色,当设置`background`后恒为`true`
// "fontSize": 40, //字体大小
// "ignoreChars": '', //忽略那些字符
// "mathExpr": false, //是否使用数学表达式
// "mathMin": 1, //表达式所使用的最小数字
// "mathMax": 9, //表达式所使用的最大数字
// "mathOperator": '' //表达式所使用的运算符,支持 `+`、`-`。不传随机使用
// "expiresDate":180 //验证码过期时间(s)
}
}
\ No newline at end of file
// 开发文档: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj // 开发文档: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
//导入验证码公共模块
const uniCaptcha = require('uni-captcha') const uniCaptcha = require('uni-captcha')
//获取数据库对象
const db = uniCloud.database(); const db = uniCloud.database();
//获取数据表opendb-verify-codes对象
const verifyCodes = db.collection('opendb-verify-codes') const verifyCodes = db.collection('opendb-verify-codes')
module.exports = { module.exports = {
async getImageCaptcha({scene}) { async getImageCaptcha({
let {deviceId} = this.getClientInfo(); scene
let res = await verifyCodes.where({scene,deviceId,state:0}).limit(1).get() }) {
console.log("res: " + JSON.stringify(res)); //获取设备id
let action = res.data.length?'refresh':'create' let {
console.log(action); deviceId,
return await uniCaptcha[action]({ platform
} = this.getClientInfo();
//根据:设备id、场景值、状态,查找记录是否存在
let res = await verifyCodes.where({
scene, scene,
width:100, deviceId,
height:44 state: 0
}) }).limit(1).get()
//如果已存在则调用刷新接口,反之调用插件接口
let action = res.data.length ? 'refresh' : 'create'
//执行并返回结果
//导入配置,配置优先级说明:此处配置 > uni-config-center
const config = require('./config')
return await uniCaptcha[action](Object.assign(
config, // 配置优先级说明:此配置 > uni-config-center
{
scene,//来源客户端传递,表示:使用场景值,用于防止不同功能的验证码混用
uniPlatform:platform
},
))
} }
} }
// 在本文件中可配置云数据库初始化,数据格式见:https://uniapp.dcloud.io/uniCloud/hellodb?id=db-init
// 编写完毕后对本文件点右键,可按配置规则创建表和添加数据
{
"opendb-verify-codes":{}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册