Skip to content

验证码 ​

这篇解决什么 ​

登录、注册要挡住机器刷接口。读完能对齐前后端开关、改滑动或点选类型、把 captchaVerification 接到登录请求,以及在生产把两边都打开。

默认端口 48080,管理端前缀 /admin-api。本地开发常见两边都关,方便联调;生产必须打开。

示意图:前端先取图、再校验轨迹;登录时把二次校验串交给 AdminAuthServiceImpl。

滑动拼图与文字点选

示意图:左侧滑动拼图 blockPuzzle,右侧文字点选 clickWord。

登录弹出验证码

示意图:点登录后弹出安全验证,通过后再带 captchaVerification 调 /system/auth/login。

为什么用行为验证码

用户拖滑块或按顺序点字,不必再敲扭曲字符。轨迹比静态图片更难被脚本批量识别。

交互流程 ​

前端组件是弹出层(mode="pop")。点登录先出验证码,通过后再提交账号密码。

示意图:check 只证明本次操作通过;登录还要再做一次 verification,串用过即失效。

名称说明仓库路径
取图POST /admin-api/system/captcha/get,@PermitAll、@TenantIgnoreruoyi-office/yudao-module-system/.../controller/admin/captcha/CaptchaController.java
一次校验POST /admin-api/system/captcha/check,校验轨迹同上
二次校验登录、注册把 captchaVerification 交给 captchaService.verification.../service/auth/AdminAuthServiceImpl.java
入参AuthLoginReqVO / AuthRegisterReqVO 继承 CaptchaVerificationReqVO.../controller/admin/auth/vo/
登录失败码AUTH_LOGIN_CAPTCHA_CODE_ERROR(1_002_000_004)yudao-module-system-api/.../enums/ErrorCodeConstants.java
注册失败码AUTH_REGISTER_CAPTCHA_CODE_ERROR(1_002_000_008)同上

get / check 未登录就能调。浏览器标识用客户端 IP 加 User-Agent,见 CaptchaController#getRemoteId。

开关打开时,doValidateCaptcha 才用 CodeEnableGroup 强校验 captchaVerification 非空,再调二次校验:

java
private ResponseModel doValidateCaptcha(CaptchaVerificationReqVO reqVO) {
    if (!captchaEnable) {
        return ResponseModel.success();
    }
    ValidationUtils.validate(validator, reqVO, CaptchaVerificationReqVO.CodeEnableGroup.class);
    CaptchaVO captchaVO = new CaptchaVO();
    captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification());
    return captchaService.verification(captchaVO);
}

登录失败会记 LoginResultEnum.CAPTCHA_CODE_ERROR。注册、以及重置密码场景的 sendSmsCode,同样走这条二次校验。

开关 ​

两套开关必须一起看。前端只决定弹不弹;后端决定认不认。

名称说明仓库路径
yudao.captcha.enable后端总闸。缺省 trueAdminAuthServiceImpl 的 @Value
开发 / 本地常为 false,方便接口联调ruoyi-office/yudao-server/src/main/resources/application-dev.yaml、application-local.yaml
生产必须 trueruoyi-office/yudao-server/src/main/resources/application-prod.yaml
VITE_APP_CAPTCHA_ENABLE前端是否渲染 VerificationisCaptchaEnable() → ruoyi-office-vben/packages/effects/hooks/src/use-app-config.ts
前端开发.env.development 为 falseruoyi-office-vben/apps/web-antd/.env.development
前端生产.env.production 为 trueruoyi-office-vben/apps/web-antd/.env.production
移动端同一环境变量名ruoyi-office-uniapp/env/.env
yaml
# application-prod.yaml
yudao:
  captcha:
    enable: true
bash
# .env.production
VITE_APP_CAPTCHA_ENABLE=true

生产必须打开

客户环境和正式发布不要关验证码。只把 false 留在本地 dev / local。生产 YAML 和 .env.production 都写成 true,两边一起生效。

两边要对齐

前端开、后端关:弹层有,登录不校验。前端关、后端开:没有 captchaVerification,登录报验证码不正确。

后端 ​

依赖已在 system 模块。Spring Boot 3 不会自动装配 AJ Captcha,要由配置类导入。

名称说明仓库路径
依赖com.anji-plus:captcha-spring-boot-starterruoyi-office/yudao-module-system/yudao-module-system-server/pom.xml
自动配置@ImportAutoConfiguration(AjCaptchaAutoConfiguration).../framework/captcha/config/YudaoCaptchaConfiguration.java
Redis 缓存cache-type: redis 时注入 StringRedisTemplate.../framework/captcha/core/RedisCaptchaServiceImpl.java
SPI 缓存META-INF/services/com.anji.captcha.service.CaptchaCacheService同模块 src/main/resources/META-INF/services/
文字输入pictureWord,4 位字母数字.../framework/captcha/core/PictureWordCaptchaServiceImpl.java
登录入口@RequestMapping("/system/auth"),POST /login.../controller/admin/auth/AuthController.java

aj.captcha 写在单体 application.yaml。底图目录当前仓库没有自备资源,缺文件时用组件自带图。

名称说明仓库路径
type默认 blockPuzzle。还可 clickWord、pictureWord、defaultruoyi-office/yudao-server/src/main/resources/application.yaml
cache-typeredis / local。生产用 Redis,多实例才一致同上
jigsaw / pic-click底图 classpath。可在 resources/images/ 自备同上
water-mark右下角水印。现网置空,避免露出品牌字同上
interference-options滑动干扰,0 / 1 / 2同上
req-*-limitget / check / verify 的分钟限流与失败锁定同上

换底图时,把图片放进 yudao-module-system-server/src/main/resources/images/jigsaw 或 pic-click,路径与配置一致即可。

Redis 挂了验证码也挂

cache-type: redis 时,取图和校验都写 Redis。本机联调先保证 127.0.0.1:6379 活着,再查登录失败是不是验证码缓存没写上。

前端 ​

管理端主应用是 web-antd。登录、注册、社交登录共用同一套组件。

名称说明仓库路径
登录页captchaEnable 为真才挂 Verification,mode="pop"ruoyi-office-vben/apps/web-antd/src/views/_core/authentication/login.vue
注册 / 社交同样先校验再提交同目录 register.vue、social-login.vue
组件blockPuzzle → 滑块,clickWord → 点选ruoyi-office-vben/packages/effects/common-ui/src/components/captcha/verification/
APIbaseRequestClient.post,不带登录 Tokenruoyi-office-vben/apps/web-antd/src/api/core/auth.ts

登录页默认 captchaType = 'blockPuzzle'。点登录若开关打开,先 verifyRef.show(),成功回调再 authLogin:

ts
async function handleLogin(values: any) {
  if (captchaEnable) {
    verifyRef.value.show();
    return;
  }
  await authStore.authLogin('username', values);
}

async function handleVerifySuccess({ captchaVerification }: any) {
  await authStore.authLogin('username', {
    ...(await loginRef.value.getFormApi().getValues()),
    captchaVerification,
  });
}
ts
export async function getCaptcha(data: any) {
  return baseRequestClient.post('/system/captcha/get', data);
}

export async function checkCaptcha(data: any) {
  return baseRequestClient.post('/system/captcha/check', data);
}

移动端 ​

UniApp 登录、注册、短信登录也读 VITE_APP_CAPTCHA_ENABLE。默认 env/.env 为 false。打开后组件在 pages-core/auth/components/verifition/,接口同样打 /system/captcha/get 与 /check。

名称说明仓库路径
登录captchaEnabled 控制是否弹出ruoyi-office-uniapp/src/pages-core/auth/login.vue
注册 / 短信登录同一开关register.vue、code-login.vue
APIoriginal: true,直接吃组件协议ruoyi-office-uniapp/src/api/login.ts

后端闸门是全局的,不按终端拆。生产若打开 yudao.captcha.enable,移动端也必须弹出并带上 captchaVerification。

换类型 ​

PC 组件只接两种行为验证码。改登录页常量,并让后端 aj.captcha.type 对上。

名称说明仓库路径
blockPuzzle滑动拼图,当前默认login.vue 的 captchaType;aj.captcha.type
clickWord文字点选Verification 的 verify-points.vue
pictureWord后端 4 位字符图,SPI 已注册PictureWordCaptchaServiceImpl
default后端三种都实例化aj.captcha.type

VerificationProps.captchaType 只有 'blockPuzzle' | 'clickWord'。要改成输入字符,需要自己做输入框,把用户输入放到组件协议的 pointJson,不能只改后端 type。

配置与操作 ​

改 yudao.captcha.enable 和 aj.captcha.type 后重启。本地常关。没有验证码 CRUD 菜单,登录页直接调 /system/captcha。

开启见 框架层。

相关篇 ​

联系我们

获取报价、演示和二开方案

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版