Skip to content

验证码组件 ​

四种纯前端交互验证码:滑块(拖到头通过)、旋转(拖滑块把图片转正)、拼图滑块(拖滑块对齐缺口)、点选(按序点击图中文字)。零第三方依赖,样式走 @fx/styles 设计 token(亮暗主题自动跟随)。

组件只负责人机交互与通过判定,服务端强校验由消费方接线:滑块/旋转/拼图通过 success 事件拿到用时,点选通过 confirm 事件拿到坐标序列(序号 + 像素坐标 + 时间戳)。

组件已随 @fx/components 提供(web 已内置依赖),无需单独安装。

vue
<script setup lang="ts">
import { FxCaptchaSlider } from "@fx/components"
const passed = ref(false)
</script>

<template>
  <FxCaptchaSlider v-model="passed" />
</template>

组件一览 ​

组件交互典型场景
FxCaptchaSlider按住滑块拖到最右端登录/注册表单门控(基座组件,可 isSlot 组合)
FxCaptchaRotate拖滑块把随机预旋转的圆图转正图片类风控验证
FxCaptchaPuzzle拖滑块把拼图块对齐缺口图片类风控验证
FxCaptchaPointSelect按提示依次点击图中文字位置文字点选风控验证

与后端对接 ​

组件只负责前端交互,完整的安全闭环由服务端三步完成:

text
① 获取题目  GET /captcha?type=puzzle
            服务端生成题目,答案写入 Redis(captcha:{id},TTL 2~5 分钟,一次性)
            └─ 返回 captchaId + 题目数据(图片 URL / 角度 / 坐标)

② 前端交互  组件完成拖动/点选(答案类 props 接服务端下发数据)

③ 提交校验  业务请求附带 captchaId + 交互结果
            服务端取答案做容差判定 → 销毁 → 返回结果

各类型的服务端数据 ​

类型① 下发给组件服务端留存③ 校验口径
滑块无(纯交互门控)无前端判定即可;可加用时/轨迹合理性复验
旋转图片 URL + answer-degreeanswerDegree 随机角用户停止角与答案差 ≤ diffDegree(默认 20°)
拼图背景图 URL + answer-xanswerX 缺口横坐标用户停留 x 与答案差 ≤ diffDistance(默认 3px)
点选服务端渲染的目标字+干扰字图片目标字坐标数组(按序)点击数一致,且第 i 次点击落在第 i 个目标字容差框内(建议半径 8~12px)

旋转/拼图通过 answer-degree / answer-x props 接收服务端答案(提供时跳过本地随机)——组件本地的 Math.random 仅适用于无服务端的演示场景。

安全要点 ​

  • 答案只存服务端:旋转的角度、拼图的缺口坐标、点选的目标字位置都不应明文下发;接服务端校验后把容差判定整体移到服务端(组件侧仅作体验提示)
  • captchaId 一次性消费(校验即销毁)+ 短 TTL + 连续失败 N 次作废,防重放与爆破
  • 点选图片由服务端渲染(目标字+干扰字+干扰线/扭曲),前端坐标按图片原始尺寸做比例换算
  • 滑块建议校验 success 事件抛出的拖动用时与轨迹合理性(匀速直线多为脚本)

注意事项 ​

  • 拼图组件用 canvas 从图片取像,图片源需允许跨域(crossOrigin="anonymous",如 picsum 等 CDN)
  • 点选组件的坐标为图片容器内像素坐标,服务端校验时注意按图片原始尺寸做比例换算