动态令牌验证是防范csrf最可靠的方式,核心在于每次敏感请求前生成、绑定并校验一次性令牌,确保请求真实出自用户主动操作;令牌须具备唯一性、随机性与时效性,推荐使用加密安全随机数生成器生成不少于32字节的令牌,并与用户会话强绑定,存于session或redis(15–30分钟过期);避免拼入url,html表单用隐藏字段、ajax优先用x-csrf-token头传递;服务端须在业务逻辑前校验,覆盖post/put/patch/delete,严格恒定时间比对,失败即返403;配套samesite=lax、二次确认、origin/referer限制及禁用get变更状态。

动态令牌验证是防范 CSRF 最可靠的方式,核心在于每次敏感请求前生成、绑定并校验一次性令牌,确保请求真实出自用户主动操作。
动态令牌的生成与绑定
令牌必须具备唯一性、随机性和时效性。推荐使用加密安全的随机数生成器(如 Go 的 crypto/rand 或 Python 的 secrets 模块),长度不少于 32 字节,并与当前用户会话强绑定。
- 服务端在渲染表单页或返回 JSON 接口元数据时,同步生成令牌并存入 session 或 Redis(带过期时间,建议 15–30 分钟)
- 避免将令牌拼接进 URL,防止泄露于日志、代理、Referer 或浏览器历史
- 同一会话可支持多令牌(例如每个表单/操作独立生成),但旧令牌应立即失效,防止重放
前端请求携带方式
根据接口类型选择安全、稳定的传递路径:
- HTML 表单:通过隐藏字段提交,如
<input type="hidden" name="csrf_token" value="xxx"> - AJAX 请求:优先放在
X-CSRF-Token请求头中;若受限于跨域或框架限制,也可作为请求体字段(如 JSON 中的_csrf字段) - 避免使用 Cookie 自动携带 CSRF 令牌(易与会话 Cookie 混淆,且 SameSite 无法替代校验逻辑)
服务端校验逻辑
校验必须在业务逻辑执行前完成,且覆盖所有状态变更类方法(POST、PUT、PATCH、DELETE),GET 请求原则上不参与 CSRF 校验(也不应承载敏感操作)。
- 提取请求中的令牌(检查 header > body > query,按优先级顺序)
- 从 session 或缓存中取出对应用户的当前有效令牌,严格比对(恒定时间比较,防时序攻击)
- 校验失败立即返回 403,不记录详细错误原因,不执行后续业务逻辑
- 成功校验后,可选择立即作废该令牌(一次性)或延长其有效期(需配合刷新机制)
配套加固措施
动态令牌是主防线,但需配合其他机制形成纵深防御:
- 设置会话 Cookie 的
SameSite=Lax(或Strict),降低自动携带风险 - 对关键操作(如转账、密码修改)增加二次确认或短时验证码,绕过纯自动化攻击链
- 限制敏感接口的 Origin 和 Referer 头(辅助手段,不可单独依赖)
- 禁用 GET 方式执行状态变更,杜绝 GET 型 CSRF 可能











