CSRF 验证失败,但仅限 IE9

Posted

技术标签:

【中文标题】CSRF 验证失败,但仅限 IE9【英文标题】:CSRF verfication failed, but only with IE9 【发布时间】:2011-11-18 12:07:22 【问题描述】:

我已经按照Django docs 中的描述设置了 CSRF(使用 Django 1.3)。它适用于 FF 和 Safari,但在 IE9 上我得到了

<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
</div>

在我找到的 Ajax 请求的响应标头中

Set-Cookie  csrftoken=8db3637951243ffb591e6b2d6998ed03; expires=Fri, 14-Sep-2012 08:01:52 GMT; Max-Age=31449600; Path=/

当在普通表单中使用它时,它可以在 IE9 中工作(即不涉及 Ajax)。

我在 nginx/1.1.2 后面使用 Django。

任何提示我在这里缺少什么?

【问题讨论】:

【参考方案1】:

如果您的表单位于 iframe 中,可能的原因是 IE 阻止第三方 cookie 的默认策略。你可以

不使用 iframe, 将 iframe 页面置于与主页相同的域下, 使用 @csrf_exempt decorator 为该特定表单禁用 CSRF,或 使用 HTTP 标头告诉浏览器允许第三方 cookie(参见Chase Seibert's excellent explanation of this issue 中的解决方法 #3)。

Django 的票#17157 建议在文档中添加关于此问题的注释。

【讨论】:

【参考方案2】:

我有同样的问题,对我来说问题是我没有指定表单动作属性。 IE 显然不允许这样做。

【讨论】:

【参考方案3】:

在 Django 的票 #17157(感谢 @akaihola 的链接)中指出,问题在于 Internet Explorer 默认会阻止第三方 cookie。因此,您可以在浏览器设置中为所有站点或仅为您的站点启用第三方 cookie。 以下是如何在 IE 7 中执行此操作(来自 this link):

    点击“工具”菜单 点击“Internet 选项” 选择“隐私”标签

选项 1:为所有网站启用第三方 cookie

    点击“高级” 选择“覆盖自动 cookie 处理” 选择“Third-party Cookies”下的“Accept”按钮并点击“OK”

选项 2:仅为 Feedjit.com 启用第三方 cookie

    点击“网站” 添加“your-domain.com”并点击“允许” 点击“确定” 选择“Third-party Cookies”下的“Accept”按钮并点击“OK”

【讨论】:

以上是关于CSRF 验证失败,但仅限 IE9的主要内容,如果未能解决你的问题,请参考以下文章

禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token %

Flask:CSRF 验证失败

由于缺少 CSRF,表单验证失败

Django 1.2.4 CSRF 验证失败

某些用户的 CSRF 验证失败

Symfony:身份验证请求失败:无效的 CSRF 令牌