图形验证码后端必须用session存储验证码值,前端通过带时间戳的img标签请求图片,提交时先校验session中值再执行业务逻辑,校验后立即清除session值并设置5分钟过期。

图形验证码后端生成要用 session 存证码值
用户提交表单时,服务端必须比对用户输入和之前生成的验证码,而浏览器无法直接读取服务端内存或文件——所以得靠 session(或等效机制如 Redis + token 关联)来暂存真实值。不存、乱存、存错地方,前端无论显示多漂亮,验证永远失败。
-
session是最简方案:生成验证码图片的同时,把明文或哈希值写入req.session.captcha(Node.js/Express)或$_SESSION['captcha'](PHP) - 别用 cookie 直接存明文验证码:容易被篡改或抓包伪造
- 别在前端用 hidden input 存原始值:等于把答案写在试卷上
- 生成后立即设置
session过期时间(比如 5 分钟),避免长期有效导致暴力试探
前端 img 标签 src 必须带唯一时间戳防缓存
验证码图片常被浏览器缓存,点刷新按钮没反应,或者连续几次请求返回同一张图——本质是 src URL 被复用,CDN 或本地缓存直接返回旧响应。
- 正确写法:
<img src="/captcha?r=" date.now alt="HTML表单如何实现图形验证码_HTML表单实现图形验证码流程【指南】" >或拼随机数Math.random() - 后端路由如
/captcha必须返回Content-Type: image/png,且禁止加Cache-Control: public - 如果用了 Nginx,检查是否配置了针对
.png的强制缓存规则,要排除/captcha路径
表单提交时后端校验顺序不能颠倒
常见错误是先查数据库、再校验验证码,结果验证码错也照样触发登录逻辑或发短信,既浪费资源又暴露接口行为。
- 必须第一步校验
captcha输入是否匹配session中的值,不匹配立刻返回错误,不往下走 - 校验通过后才清空
session.captcha(防止重放) - 大小写敏感?要看你生成时是否转小写——多数库默认区分,建议统一转
toLowerCase()后比对 - 用户输错三次,可考虑临时封禁该
session或 IP,但注意别影响正常用户共享出口 IP
用 canvas 或 SVG 渲染时字体和抗锯齿要手动关
用前端 JS 动态画验证码(比如用 canvas),看似省后端,实则极易被 OCR 批量识别——因为默认字体清晰、无干扰、高对比。
立即学习“前端免费学习笔记(深入)”;
- 必须手动关闭
ctx.textRendering = "optimizeLegibility",启用低质量渲染 - 加噪点:用
ctx.fillRect(Math.random()*w, Math.random()*h, 1, 1)撒点 - 扭曲文字路径:不用
fillText直接写,改用strokeText+ 随机偏移每个字符 x/y - 别用系统默认字体(如 Arial),嵌入简单手写体 ttf 并用
ctx.font加载,但注意跨域和性能











