我的项目正在多个 3rd 方站点上部署 iframe,这些站点都是已知的并在 django 应用程序中注册。
在这些 iframe 中,用户可以触发一些 ajax 形式的事件。直接打开网站,一切正常。如果我打开包含 iframe 的第 3 方站点,django 在触发 ajax 事件(403)后会抛出错误,表示 CSRF 失败。
在表单中我使用了在html中设置的{% csrf_token %}。但是,当通过 iframe 调用站点时,它不会设置相应的 cookie(在浏览器中使用检查模式发现两者)。
我确实知道我可以使用装饰器
@csrf_exempt
,但这会同时禁用 csrf 保护,这是我不想做的。
所以我的问题是:
非常感谢您的宝贵时间! :)
我正在处理同样的问题,Midas Gossye 的答案对我不起作用。我的解决方案是在
settings.py
中进行以下编辑,以便当站点位于 iframe 中时让 Django 设置 CSRF cookie。
CSRF_COOKIE_SAMESITE = "None"
,因为您希望将 CSRF cookie 从您的站点发送到 iframe 中包含该 cookie 的站点(source)CSRF_COOKIE_SECURE = True
将 CSRF cookie 标记为安全。这意味着浏览器将确保此 cookie 仅通过 HTTPS 发送(source)。您应该拥有它,因为它更安全,并且未来版本的浏览器只会发送 SameSite=None(如果它也标记为安全)的 cookie。CSRF_TRUSTED_ORIGINS
,事实上,出于安全原因,可以说您不应该这样做。这是因为,如果用户通过 iframe 使用您的网站,则 POST 请求仍然来自您的网站,而不是来自其他服务器。仅当 POST 请求来自另一台服务器上的站点时才需要此设置(源)您可能需要清除 Django 站点上的 cookie(应包括 csrftoken cookie),然后重新加载并检查新的 csrftoken 是否标记为“安全”并且没有“SameSite”。
现在,当第 3 方页面在 iframe 中包含您的页面时,应设置 csrftoken cookie(您可以通过让您的页面使用 Javascript 打印
csrftoken
cookie 来确认),并且您应该能够从以下位置发出成功的 POST 请求你的 iframe-d Django 网站。
这是我在 settings.py 文件中所做的更改,以获得类似的工作:
X_FRAME_OPTIONS = 'ALLOW-FROM example.com'
CSRF_TRUSTED_ORIGINS = ['example.com']
CSRF_COOKIE_SAMESITE = None
其中 example.com 是您插入 iframe 的域。 最后一个选项最近才在 Django 中引入,因此根据您的版本,可能没有必要。