打开新的浏览器选项卡会使 Django 的 CSRF 令牌无效,从而阻止表单提交
Posted
技术标签:
【中文标题】打开新的浏览器选项卡会使 Django 的 CSRF 令牌无效,从而阻止表单提交【英文标题】:Opening a new browser tab invalidates Django's CSRF token, preventing form submission 【发布时间】:2017-09-03 21:40:34 【问题描述】:在第二个浏览器选项卡中打开 Django 1.10 应用程序会刷新 CSRF 令牌。这会破坏第一个选项卡中的所有表单 - 即,以前打开的表单无法再提交,因为旧的 CSRF 令牌现在无效。
如何避免这种行为?
分步示例:
-
用户正在选项卡 A 中查看表单。
用户在选项卡 B 中打开应用程序。
用户返回选项卡 A 并尝试提交表单。
错误:禁止 (403)。 CSRF 验证失败。请求中止。
一些细节:
我真的很想在应用程序中允许多标签浏览。
Django 1.10 release notes 记录了对 CSRF 机制的更改:
为了防止 BREACH 攻击,现在的 CSRF 保护机制 在每个请求上更改表单令牌值(同时保持 可用于验证不同令牌的不变秘密)。
Django 的1.9 CSRF documentation 对可用性问题的描述非常好。这一段已经在1.10 CSRF documentation 中删除了,但它似乎描述了我遇到的确切问题:
为什么不为每个请求使用一个新令牌?
从 UI 为每个请求生成一个新令牌是有问题的 透视,因为它使所有以前的形式无效。大多数用户 如果发现在您的网站上打开新标签页会非常不高兴 使他们刚刚花时间填写的表格无效 选项卡或他们通过后退按钮访问的表单无法 填写完毕。
【问题讨论】:
这真的很有趣。由于没有记录如何绕过这种行为,我建议你在 Django 的 IRC 频道上提问。你会在那里找到一些 Django 核心开发人员,他们可能会回答。 谢谢@xyres,我试试看。 【参考方案1】:如果您在视图中使用 @csrf_protect 装饰器,请尝试使用 @csrf_exempt 装饰器。
views.py之前:
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def view(request):
# Render Something
views.py之后:
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def view(request):
# Render Something
抱歉回复晚了。 迟到总比没有好。
【讨论】:
这不是一个好主意。它会禁用视图的 csrf 保护。以上是关于打开新的浏览器选项卡会使 Django 的 CSRF 令牌无效,从而阻止表单提交的主要内容,如果未能解决你的问题,请参考以下文章