[英]Django + Caddy = CSRF protection issues
我在 docker 容器中部署了带有 Daphne (ASGI) 的 Django 4 应用程序。 我在前面使用 Caddy 作为反向代理。 它可以工作,除了我无法填写任何表格,因为 CSRF 保护启动。例如,没有管理员登录。
我目前可以通过两种方式访问管理界面:
选项 1 有效。 我可以登录到管理界面,就像我在本地运行开发服务器一样。 一切都按预期工作。
但是,选项 2(球童反向代理)不起作用。 我可以访问 Django 并加载页面,但任何表单提交都将被阻止,因为 CSRF 保护启动。
CSRF verification failed. Request aborted.
Reason given for failure:
Origin checking failed - https://<mydomain.com> does not match any trusted origins.
我的 Caddyfile 包含以下内容:
<mydomain.com> {
reverse_proxy localhost:8088
}
localhost:8088 是我的 docker 容器暴露的端口。
为了消除潜在问题,我在配置文件中将以下内容设置为 false:
SECURE_SSL_REDIRECT
(导致重定向循环,可能与反向代理有关)SESSION_COOKIE_SECURE
(我宁愿将其设置为 True,但目前我不知道)CSRF_COOKIE_SECURE
(同注)我可以在网上找到的唯一 Django-Caddy 示例已经过时,并且指的是旧版本的 Caddy 和/或 Django。 Django 与 Daphne 一起部署在 ASGI 上。
我已经看到建议更改CSRF_TRUSTED_ORIGINS
的帖子,但是我必须添加一个已经在 ALLOWED_HOSTS 列表中的主机似乎不正确。 这也无法解释为什么它直接在 docker 容器上工作,除非 localhost 是 CSRF 的特例。
版本:
知道出了什么问题,我应该如何调试此类问题?
终于知道是怎么回事了。
我首先想知道从球童发送到 django 的确切 HTTP 请求:
sudo tcpdump -i lo -A -n port 8088
这证实了:
Origin
和Referer
标头已正确设置csrftoken
cookie 已正确发送一旦知道了这一点,我就可以从 django 中挖掘代码。 具体来说就是 CSRF 中间件中的这个 function 。
综上所述:
Origin
header 为http://
,因为请求不安全。 就我而言,它是https://
因为我的浏览器正在通过 https 与 Caddy 交谈Origin
header 与 CSRF 中间件所期望的不匹配,所以请求被拒绝这实际上是一个简单的修复。
由于我们知道Caddy 将始终忽略浏览器X-Forwarded-Proto
并自行设置,因此我们可以将SECURE_PROXY_SSL_HEADER添加到 django 的settings.py
中:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
瞧!
现在我也可以将这些设置为 true:
编辑这是 Caddyfile,根据要求:
service.mywebsite.com {
reverse_proxy localhost:8088
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.