安全验证 xSafeVerify
预览
介绍
全端 x-skia-u 绘制的人机安全验证。拼图模式:把用户图片画到画板上,随机位置挖出内置图形缺口,拖动随机图形与缺口重合即通过;字符模式:把一组字符随机渲染到用户图片上,按提示顺序点选(点选处圆形数字索引,再点一次取消),点满自动校验。
平台兼容
| Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|---|---|---|---|---|---|---|---|
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.9.9 |
文件路径
ts
@/uni_modules/tmx-ui/components/x-safe-verify/x-safe-verify.uvue使用
ts
<x-safe-verify></x-safe-verify>Props 属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| mode | 验证模式jigsaw:拖动随机图形与图片缺口重合char:按顺序点选图中字符 | XSafeVerifyMode | 'jigsaw' |
| src | 背景图片地址,支持网络图片和本地图片网络图片在 App 端需要配置下载合法域名 | string | '' |
| width | 宽,允许使用数字,百分比,带单位的字符串 | string | '100%' |
| height | 高,允许使用数字,带单位的字符串 | string | '180' |
| round | 圆角 | string | '10' |
| shape | 拼图模式的内置图形,random 为每次随机一种puzzle 拼图块 / circle 圆形 / square 方形 / triangle 三角 / diamond 菱形hexagon 六边形 / star 五角星 / heart 心形 / cross 十字 | XSafeVerifyShape | 'random' |
| pieceSize | 拼图模式下图形边长,px,0 为按画板自动 | number | 0 |
| tolerance | 允许的误差 px,0 为按图形大小自动(图形边长 16%) | number | 0 |
| chars | 字符模式下用户指定的按顺序字符组,例如 '天地玄黄'为空时从内置字库中随机抽取 count 个不重复字符 | string | '' |
| count | 字符模式随机字符数量,2-8,提供 chars 时以 chars 长度为准 | number | 4 |
| fontSize | 字符字号 px,0 为自动 | number | 0 |
| maskColor | 拼图缺口遮罩色 | string | 'rgba(0,0,0,0.55)' |
| lineColor | 缺口和图形描边色 | string | 'rgba(255,255,255,0.95)' |
| activeColor | 激活色,空取全局主题色,用于序号索引 | string | '' |
| successColor | 验证通过色 | string | 'success' |
| failColor | 验证失败色 | string | 'error' |
| showTips | 是否显示底部提示 | boolean | true |
| tipsRender | 状态提示渲染位置dom:渲染成组件底部小字提示层,可用 tips 插槽自定义,默认canvas:画在画布上,不依赖 DOM 层级,DOM 会被原生画布遮住时用它 | union | 'dom' |
| tips | 自定义未验证时的提示文本 | string | '' |
| tipsSuccess | 自定义验证成功的提示文本 | string | '' |
| tipsFail | 自定义验证失败的提示文本 | string | '' |
| tipsColor | 提示文本颜色,空为白色 | string | '' |
| resetAuto | 验证失败后是否自动重置(重新出题) | boolean | true |
| resetDelay | 自动重置的延时毫秒 | number | 900 |
| autoVerify | 拼图模式松手后是否自动校验,false 时由 ref.verify() 手动校验 | boolean | true |
| disabled | 是否禁用交互 | boolean | false |
Events 事件
| 名称 | 参数 | 说明 |
|---|---|---|
| ready | - | 题目已生成(首次就绪以及每次重新出题时触发) |
| success | mode: string | 验证通过 |
| fail | mode: stringreason: string | 验证失败 |
| error | message: string | 图片加载失败等错误 |
| reset | - | 重置完成后触发 |
| click | char: stringorder: number | 字符模式点选字符时触发 |
Slots 插槽
| 名称 | 说明 | 数据 |
|---|---|---|
| tips | 底部提示插槽,文本随状态变化 | text: string |
Ref 方法
| 名称 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| reset | - | - | 重置,重新出题并清空操作 * |
| refresh | - | - | 同reset,重新出题 * |
| clear | - | - | 只清空当前操作,题目不变 * |
| verify | - | - | 手动校验当前状态 * |
| getStatus | - | - | 当前状态 load/ready/success/fail * |
| getTries | - | - | 当前题目失败次数 * |
| getAnswer | - | - | 当前题目答案 * |
| getSelected | - | - | 用户当前操作结果 * |
| getImage | - | - | 导出画板图片 * |
示例文件路径
json
/pages/qita/safe-verify示例源码
uvue
vue
<template>
<!-- #ifdef MP-WEIXIN -->
<page-meta :page-style="`background-color:${xThemeConfigBgColor}`">
<navigation-bar :background-color="xThemeConfigNavBgColor" :front-color="xThemeConfigNavFontColor"></navigation-bar>
</page-meta>
<!-- #endif -->
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">安全验证 xSafeVerify</x-text>
<x-text color="#999999">
全端 x-skia-u 原生绘制。拼图模式:拖动随机图形与图片缺口重合;字符模式:按顺序点选图中字符,点选处显示圆形数字索引,再点一次取消。
</x-text>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">拼图拖动验证</x-text>
<x-text color="#999999" class="mb-8">拖动右侧的图形到左侧缺口处,重合即通过。松手自动校验,失败自动换题。</x-text>
<x-safe-verify ref="jigsawRef" src="https://cdn.tmui.design/xui/tmui4.0banner1.jpg" height="200"
@ready="onReady" @success="onSuccess" @fail="onFail" @error="onError"></x-safe-verify>
<x-button class="mt-20" :block="true" @click="resetJigsaw">重置/换题</x-button>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">拼图验证:指定图形与颜色</x-text>
<x-text color="#999999" class="mb-8">shape 指定内置图形(puzzle/circle/square/triangle/diamond/hexagon/star/heart/cross)。</x-text>
<x-safe-verify ref="starRef" shape="star" height="200" :piece-size="64" :tolerance="8" line-color="#F7B500"
src="/static/temqrcoderPicCanvas.jpg" @success="onSuccess" @fail="onFail"></x-safe-verify>
<x-button class="mt-20" :block="true" color="warn" @click="resetStar">重置/换题</x-button>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">拼图验证:自己控制校验</x-text>
<x-text color="#999999" class="mb-8">auto-verify 设为 false 后,松手不校验,由 ref.verify() 触发。</x-text>
<x-safe-verify ref="manualRef" height="200" :auto-verify="false" :piece-size="56"
src="https://cdn.tmui.design/xui/tmui4.0banner1.jpg" @success="onSuccess" @fail="onFail"></x-safe-verify>
<x-sheet class="flex flex-row mt-20">
<x-button width="48%" @click="doVerify">手动校验</x-button>
<x-button width="48%" class="mx-10" color="warn" @click="resetManual">重置</x-button>
</x-sheet>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">中文字符顺序验证(内置随机字符)</x-text>
<x-text color="#999999" class="mb-8">从内置字库随机取 4 个不重复字符随机渲染,按顶部提示顺序点选,点满自动校验。</x-text>
<x-safe-verify ref="charRef" mode="char" :count="4" height="220"
src="https://cdn.tmui.design/xui/tmui4.0banner1.jpg"
@success="onSuccess" @fail="onFail" @click="onCharClick"></x-safe-verify>
<x-button class="mt-20" :block="true" @click="resetChar">重置/换题</x-button>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">中文字符顺序验证(自定义字符组)</x-text>
<x-text color="#999999" class="mb-8">chars 传入按顺序的字符组,用它来控制答案顺序。</x-text>
<x-safe-verify ref="charsRef" mode="char" chars="天地玄黄" height="220" :font-size="30"
src="https://cdn.tmui.design/xui/tmui4.0banner1.jpg" @success="onSuccess" @fail="onFail"></x-safe-verify>
<x-sheet class="flex flex-row mt-20">
<x-button width="48%" @click="resetChars">重置/换题</x-button>
<x-button width="48%" class="mx-10" color="warn" @click="showResult">查看用户点选结果</x-button>
</x-sheet>
</x-sheet>
<x-sheet>
<x-text font-size="18" class=" text-weight-b mb-8">弹层内使用</x-text>
<x-text color="#999999" class="mb-8">弹层动画结束后再挂画布,所以要在 @open 里 v-if。</x-text>
<x-modal @open="onModalOpen" @close="show=false" height="370">
<template v-slot:trigger>
<x-button :block="true">打开弹层验证</x-button>
</template>
<x-safe-verify v-if="show" ref="modalRef" mode="char" chars="上善若水" height="200"
src="https://cdn.tmui.design/xui/tmui4.0banner1.jpg" @success="onSuccess" @fail="onFail"></x-safe-verify>
</x-modal>
</x-sheet>
</template>
<script lang="uts" setup>
const jigsawRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const starRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const manualRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const charRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const charsRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const modalRef = ref<XSafeVerifyComponentPublicInstance | null>(null)
const onReady = () => {
console.log('x-safe-verify 题目已生成')
}
const onSuccess = (mode : string) => {
uni.showToast({ title: '验证通过:' + mode, icon: 'success' })
}
const onFail = (mode : string, reason : string) => {
uni.showToast({ title: '验证失败:' + reason, icon: 'error' })
}
const onError = (message : string) => {
uni.showToast({ title: message, icon: 'none' })
}
const onCharClick = (char : string, order : number) => {
console.log('点选字符', char, order)
}
const resetJigsaw = () => {
jigsawRef.value?.reset()
}
const resetStar = () => {
starRef.value?.reset()
}
const resetManual = () => {
manualRef.value?.clear()
}
const doVerify = () => {
manualRef.value?.verify()
}
const resetChar = () => {
charRef.value?.reset()
}
const resetChars = () => {
charsRef.value?.reset()
}
const showResult = () => {
const el = charsRef.value
if (el == null) return
uni.showToast({ title: '你点的顺序:' + el.getSelected() + ' 状态:' + el.getStatus(), icon: 'none' })
}
const show = ref(false)
const onModalOpen = () => {
show.value = true
}
</script>
<style>
</style>