django - Django:没有在 iframe 中设置 CSRF Cookie——没有 csrf 豁免的解决方法
问题描述
我的项目正在几个 3rd 方站点上部署 iframe,这些站点都是已知的并在 django 应用程序中注册。
在这些 iframe 中,用户可以触发一些 ajax 形式的事件。直接打开网站,一切正常。如果我打开包含 iframe 的第 3 方站点,django 在触发 ajax 事件(403)后会抛出错误,说 CSRF 失败。
在表单中,我使用了在 html 中设置的 {% csrf_token %}。但是,当通过 iframe 调用站点时,它没有设置相应的 cookie(在浏览器中都使用检查模式发现)。
我确实知道我可以使用装饰器@csrf_exempt
,但这会同时禁用 csrf-protection,我不想这样做。
所以我的问题是:
- 当整个页面通过 iframe 加载时,为什么 django 不设置 CSRF Cookie?
- 是否可以让 django 设置 cookie 或者是否可以只从 csrf 中排除已知的 url?
- 有没有我看不到的方法?
非常感谢您的时间!:)
解决方案
我正在处理同样的问题,Midas Gossye 的回答对我不起作用。settings.py
我的解决方案是在站点位于 iframe 中时进行以下编辑以让 Django 设置 CSRF cookie。
- 设置
CSRF_COOKIE_SAMESITE = None
,因为您希望将 CSRF cookie 从您的站点发送到在 iframe 中包含它的站点(源) - 确保 Django 将 CSRF cookie 标记为安全的,使用
CSRF_COOKIE_SECURE = True
. 这意味着浏览器将确保此 cookie 仅通过 HTTPS 发送(来源)。您应该拥有它,因为它更安全,并且未来版本的浏览器只会发送带有 SameSite=None 的 cookie,前提是它也被标记为安全。 - 您不需要
CSRF_TRUSTED_ORIGINS
像以前的答案之一那样设置,事实上,出于安全原因,您不应该这样做。这是因为如果用户通过 iframe 使用您的站点,则 POST 请求仍然来自您的站点,而不是来自其他服务器。仅当 POST 请求来自另一台服务器上的站点时才需要此设置(来源)
您可能需要清除 Django 站点上的 cookie(应该包括 csrftoken cookie),然后重新加载并检查新的 csrftoken 是否标记为“安全”并且没有“SameSite”。
现在,当第 3 方页面在 iframe 中有您的页面时,应该设置 csrftoken cookie(您可以通过让您的页面使用 Javascript 打印csrftoken
cookie 来确认),并且您应该能够从 iframe-d 发出成功的 POST 请求Django 网站。
推荐阅读
- html - 如何使用 scss 更改primeng 面板菜单样式
- javascript - Webpack 从 v4 迁移到 v5,expose-loader 抛出错误
- php - 如何从mysql中的第一列值获取第二列值
- flutter - 在flutter中使用LDAP目录访问登录
- ios - “在范围内找不到类型‘GADInterstitialAd’”错误
- c# - 在 .Net 5 项目中引用兼容的 .Net 框架 dll,但出现异常
- python - 在 FPDF 对象的 json 视图中上传字符串
- c++ - 在 Microsoft vc++ 1.52 中关闭寄存器变量
- symfony - 为什么我的应用可以在本地运行,但不能在 Heroku 上运行?
- pyspark - pyspark 可视化决策树