Skip to content

5.3 验证码机制 ​

概述

图形验证码由 utility/captcha 生成:6 位字符(排除易混淆字符)、PNG 渲染(TTF 字体 + 干扰线/噪点)、Redis 缓存 300 秒、一次性校验。字体缺失自动降级 SVG 渲染。

生成流程(GET /api/captcha) ​

text
1) 生成随机码:captcha.length 位(默认 6,范围 4~8),
   字符集 captcha.chars(默认排除 0O、1lI 等易混淆字符)
2) 生成 uuid 作为缓存键
3) 缓存:easygoadmin:captcha:{uuid} = 验证码值,TTL captcha.expire(300s)
4) 渲染 PNG:TTF 字体(resource/static/fonts/Vera.ttf)+ 干扰线(默认 8 条)
   + 噪点(默认 500 个);字体缺失降级 SVG
5) 返回 {"key": uuid, "captcha": "data:image/png;base64,..."}(前端直接展示)

校验流程(captcha.Verify) ​

text
Verify(ctx, key, code):
  1) GET easygoadmin:captcha:{uuid}(命中即删除——一次性校验)
  2) 未命中 → 校验失败(过期或已用过)
  3) 命中 → 与提交值比对(大小写不敏感处理)
  4) 配置 captcha.bypassCode 且提交值相等 → 免校验直接通过
     (仅开发调试使用,生产环境必须留空)

配置项(manifest/config/config.yaml) ​

yaml
captcha:
  expire: 300                 # 有效期(秒)
  bypassCode: "618618"        # 万能验证码:携带该值免校验,仅开发调试使用,生产留空
  length: 6                   # 字符数,取值范围 4 到 8
  chars: "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"  # 字符集,已排除易混淆字符
  fontPath: "resource/static/fonts/Vera.ttf" # TTF 字体路径,缺失降级 SVG
  imageWidth: 160             # 图片宽度(字符放不下时自动加宽防裁剪)
  imageHeight: 50             # 图片高度
  fontSize: 40                # 字体大小
  noiseLines: 8               # 干扰线数量(越多越难识别)
  noiseDots: 500              # 噪点数量

使用场景 ​

场景行为
登录提供 key 时强制校验(auth Login 第 1 步)
令牌兑换认证入口,与登录同享 authLimit 严阈值
开发调试code 填 bypassCode(默认 618618)免校验
生产bypassCode 必须留空(发布检查清单项)

安全要点 ​

  • 一次性:命中即删,防重放(同一验证码不能二次使用)
  • 短 TTL:300 秒过期,防拖库后长期有效
  • 独立限流:/api/captcha 属认证入口,受 authLimit=10/分钟/IP 约束(防刷图)
  • 缓存层:经 utility/cache(Redis 优先、内存降级)——内存降级时验证码单实例内有效

常见问题 ​

症状原因与处理
验证码图片不显示后端未启动 / /api/captcha 被限流;字体缺失不影响(降级 SVG)
填对了也报验证码错误已用过(一次性)或超 300s;重新获取
前端一直验证码错误但后端日志正常检查 key 是否与图片配套(每次生成 key 不同)
生产环境想跳过验证码禁止配置 bypassCode;调试可在测试环境进行

小蚂蚁云团队 · 提供技术支持