Heroku 上的 Django CSRF_COOKIE_DOMAIN
Posted
技术标签:
【中文标题】Heroku 上的 Django CSRF_COOKIE_DOMAIN【英文标题】:Django CSRF_COOKIE_DOMAIN on Heroku 【发布时间】:2021-03-04 01:02:09 【问题描述】:所以我们将 Django 应用程序部署到 Heroku,一切都运行良好。直到我看了饼干。我有app-staging.herokuapp.com
和.app-staging.herokuapp.com
的csrftoken
cookie。但是当我设置CSRF_COOKIE_DOMAIN = 'app-staging.herokuapp.com'
时,我会自动得到错误的东西.app-staging.herokuapp.com
。
我尽我所能,但没有任何帮助。我尝试了当前的 Firefox (83.0) 和 Chromium。最大的问题是对 CSRF 令牌的无效检查。由于域不匹配它是无效的。
csrftoken=E9sdyx5U61IaFP3YNJHk3ZKtnllkEnyZ6i9eimHYD31sn4qXRXv7FBDOpPfpWhyt; Domain=app-staging.herokuapp.com; expires=Fri, 19 Nov 2021 15:33:52 GMT; Max-Age=31449600; Path=/; SameSite=Lax; Secure
请不要建议我设置CSRF_COOKIE_DOMAIN = None
。如果一个 Django 实例将在更多域上运行,我将需要解决相同的问题。我们必须尽快完成。
【问题讨论】:
【参考方案1】:我做了一点点挖掘并卡在 csrf 中间件上,请参阅下面的代码。那里的good_referer
设置为app-staging.herokuapp.com:49461
,但referer.netloc
只是app-staging.herokuapp.com
,所以函数is_same_domain
不会匹配它们,因为它会抛出错误:Referer checking failed - app-staging.herokuapp.com does not match any trusted origins."
good_referer = (
settings.SESSION_COOKIE_DOMAIN
if settings.CSRF_USE_SESSIONS
else settings.CSRF_COOKIE_DOMAIN
)
if good_referer is not None:
server_port = request.get_port()
if server_port not in ('443', '80'):
good_referer = '%s:%s' % (good_referer, server_port)
else:
try:
# request.get_host() includes the port.
good_referer = request.get_host()
except DisallowedHost:
pass
# Create a list of all acceptable HTTP referers, including the
# current host if it's permitted by ALLOWED_HOSTS.
good_hosts = list(settings.CSRF_TRUSTED_ORIGINS)
if good_referer is not None:
good_hosts.append(good_referer)
if not any(is_same_domain(referer.netloc, host) for host in good_hosts):
reason = REASON_BAD_REFERER % referer.geturl()
return self._reject(request, reason)
来源: https://github.com/django/django/blob/master/django/middleware/csrf.py#L262
【讨论】:
以上是关于Heroku 上的 Django CSRF_COOKIE_DOMAIN的主要内容,如果未能解决你的问题,请参考以下文章
RabbitMQ 上的 Heroku、Django 和 celery
Heroku 上的 webpack 和 django:collectstatic 之前的捆绑