登录
首页 >  文章 >  前端

CSRFToken防跨站攻击怎么用

时间:2026-05-07 11:24:59 287浏览 收藏

CSRF Token 并非简单插入模板标签就能奏效的安全补丁,而是一套需要服务端(严格绑定 session、动态生成且生命周期可控)、前端(从 DOM 安全提取、手动注入请求头或表单、杜绝硬编码与不安全存储)和全链路(覆盖 API、上传、GraphQL 等所有状态变更入口)协同严丝合缝的防御体系;任何一环松动——如多标签页 Token 冲突、缓存导致 Token 过期、AJAX 未携带 header、校验遗漏接口——都会让防护瞬间崩塌,只留下反复报错的 403 和形同虚设的安全假象。

HTML中如何使用CSRF Token防止跨站请求伪造

CSRF Token 不是加个 {% csrf_token %} 就能防住的——它必须和服务端 session 生命周期、传输路径、前端提取方式三者严丝合缝,否则你看到的只会是反复出现的 403 ForbiddenInvalid CSRF token

服务端生成的 Token 必须绑定当前 session

Token 值不能硬编码、不能复用、不能从 URL 或 localStorage 读取。浏览器里看到的 csrf_token 值,必须由服务端在渲染 HTML 前实时生成,并写入当前用户 session(或加密后存入 Cookie,但需设 SameSite=Lax)。

  • Django 默认将 Token 存 session;若改用 CSRF_USE_SESSIONS = False,则 Token 存 Cookie,此时响应头必须含 Set-Cookie: csrftoken=...; SameSite=Lax
  • Flask + flask-wtf 中,{{ form.hidden_tag() }} 自动注入 Token,但前提是请求已触发 session 初始化(比如用户已登录或访问过带 session 的路由)
  • Express 使用 csrf-protection 时,中间件必须挂载在 body-parser 之后、路由之前,否则 req.body 为空导致校验失败

前端必须从 DOM 安全提取,不能硬编码或跨域传

Token 不会自动进 AJAX 请求体或 header,前端必须手动提取并携带;且不能把值写死在 JS 里,也不能从第三方来源(如 URL 参数、localStorage)获取——XSS 漏洞下这些地方极易被读取。

  • 推荐方式:在 HTML 中用 ,JS 里用 document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') 获取
  • 表单提交可直接用 hidden 字段:<input type="hidden" name="csrf_token" value="{{ csrf_token }}">,但仅适用于传统 form.submit()
  • fetch 发送 POST/PUT/DELETE 时,必须显式设置 header:headers: { 'X-CSRF-Token': token };若服务端没配置从 header 读取(如 Django 需设 CSRF_HEADER_NAME = 'HTTP_X_CSRF_TOKEN'),照样 403

多标签页、页面刷新、缓存是高频翻车点

看似是前端漏传,实际八成是服务端生命周期处理出错。

  • 多标签页同时打开同一页面 → 若服务端启用“一次性 Token”(如某些 PHP 实现),第二个标签提交时 Token 已被消耗,直接报错;应改用“每会话单 Token”模式
  • 页面后退再提交 → 浏览器可能缓存旧 HTML(含过期 Token),需在服务端响应加 Cache-Control: no-store, no-cache
  • AJAX 提交前未检查 Token 是否仍有效(例如用户长时间未操作导致 session 过期),应配合 403 响应做静默刷新或跳登录

最常被忽略的是:Token 校验必须发生在所有敏感操作入口,包括 API 路由、文件上传接口、甚至 GraphQL mutation resolver —— 只要涉及状态变更,就必须走校验链。漏掉一个,就等于整套防护形同虚设。

今天关于《CSRFToken防跨站攻击怎么用》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>