You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Flask JWT Extended中将csrf_access_token存入Cookie为何被认为安全?

Flask JWT Extended中CSRF令牌存Cookie的安全原理

你的核心疑问在于:恶意网站发起跨域POST请求时,浏览器会自动携带目标站点的Cookie,那存Cookie里的csrf_access_token岂不是会被攻击者利用? 其实这是对同源策略和CSRF防护逻辑的误解,下面拆解关键原理:

1. 浏览器同源策略禁止跨域读取Cookie

浏览器的同源策略(Same-Origin Policy)会严格限制不同域名下的JavaScript代码访问其他域的Cookie。也就是说:

  • 你的网站是your-domain.com,恶意网站是evil.com,evil.com的JS代码无法通过document.cookie读取your-domain.com下的任何Cookie(包括access_token和csrf_access_token)。
  • 只有同源页面(比如你自己的/logoutpage)才能读取这些Cookie,这也是你能在登录成功后,把csrf_access_token从Cookie取出来放到表单隐藏字段里的原因。

2. CSRF攻击的核心是「利用浏览器自动带Cookie,但拿不到令牌」

CSRF攻击的本质是:攻击者诱导用户在已登录你的网站的情况下,访问恶意网站,恶意网站通过表单/JS发起对你接口的请求,此时浏览器会自动携带你的网站的Cookie(这是浏览器的默认行为,和同源策略不冲突)。但关键问题是:

  • 攻击者无法获取csrf_access_token的具体值,因为跨域JS读不到Cookie。
  • 你的后端接口(比如/logout)会验证两个东西:请求中是否携带了正确的csrf_token参数(比如表单里的隐藏字段),以及这个参数值是否和Cookie里的csrf_access_token一致。
  • 攻击者没法在恶意表单里填上正确的csrf_token值,所以后端会拒绝这个请求,攻击失败。

3. 结合你的代码理解

看你提供的代码:

@app.route("/login", methods=["POST"])
def login():
    username = request.form.get("username", None)
    password = request.form.get("password", None)
    response = jsonify({"msg": "login successful"})
    access_token = create_access_token(identity="example_user")
    set_access_cookies(response, access_token)
    return response

@app.route("/logoutpage", methods=["GET"])
@jwt_required()
def logout_page():
    logout = """<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>LOGOUT</title>
  </head>
  <body>
    <h1>LOGOUT</h1>
    <form action="/logout" method="post">
    <input type="hidden" name="csrf_token" value="{{csrfval}}">
      <input type="submit" value="Logout">
    </form>
  </body>
</html>"""
    return render_template_string(logout, csrfval=request.cookies.get("csrf_access_token"))
  • 登录时,set_access_cookies会把access_token和csrf_access_token都存在your-domain.com的Cookie里,且这些Cookie默认是HttpOnly(防止XSS攻击读取)、SameSite=Lax/Strict(进一步限制跨域携带)。
  • 访问/logoutpage时,你的后端可以读取同源的Cookie,把csrf_access_token的值填充到表单的隐藏字段里。用户提交表单时,这个值会作为csrf_token参数发送给后端,后端验证它和Cookie里的csrf_access_token匹配,才会执行登出操作。
  • 恶意网站的表单根本没法拿到这个csrfval的值,所以提交的请求会因为缺少正确的csrf_token参数被拒绝。

总结

把csrf_access_token存Cookie的核心安全逻辑是:

  • 同源页面可以读取并使用这个令牌,合法请求能通过验证。
  • 跨域攻击者无法读取令牌,无法构造出符合要求的请求,从而阻断CSRF攻击。

内容的提问来源于stack exchange,提问作者MW_DEVEL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:01:08