对 Django 的请求中缺少自定义标头

Posted

技术标签:

【中文标题】对 Django 的请求中缺少自定义标头【英文标题】:Custom headers missing in requests to Django 【发布时间】:2015-09-25 18:18:47 【问题描述】:

上下文:我编写了一个 Django 应用程序,现在已将其部署到 Elastic Beanstalk (AWS)。

在本地开发中,我一直在使用自定义请求标头 SESSION_TOKEN,然后我可以使用 request.META.get('HTTP_SESSION_TOKEN') 访问它。在生产中,我看到了错误,因为该标头不可访问(也就是我的 Django 服务器看到的所有请求中都缺少它)。

此外,我的其他标准标头工作正常,只是缺少自定义标头。注意我没有设置HTTP_AUTHORIZATION,这和Authorization header missing in django rest_framework, is apache to blame?不是同一个问题。

出了什么问题?如何在生产环境中访问我的后端的自定义标头?

【问题讨论】:

【参考方案1】:

SESSION_TOKEN 标题很可能被某些东西剥离了。来自Django security advisory:

当 HTTP 标头被放入 WSGI 环境时,它们通过转换为大写、将所有破折号转换为下划线并在 HTTP_ 前面添加来进行规范化。例如,标头 X-Auth-User 将在 WSGI 环境中变为 HTTP_X_AUTH_USER(因此也在 Django 的 request.META 字典中)。

不幸的是,这意味着 WSGI 环境无法区分包含破折号的标头和包含下划线的标头:X-Auth-User 和 X-Auth_User 都变为 HTTP_X_AUTH_USER。这意味着,如果以对安全敏感的方式使用标头(例如,从前端代理传递身份验证信息),即使代理小心地剥离了 X-Auth-User 的任何传入值,攻击者也可能会被能够提供 X-Auth_User 标头(带下划线)并绕过此保护。

还有最重要的一点信息:

为了防止此类攻击,默认情况下,nginx 和 Apache 2.4+ 都会从传入请求中去除所有包含下划线的标头。 Django 的内置开发服务器现在也这样做了。不建议将 Django 的开发服务器用于生产使用,但匹配常见生产服务器的行为会减少部署期间行为更改的表面积。

如果您有任何自定义标题,则应使用连字符。

【讨论】:

将我的请求中的标头设置为Session-Token 并将它们读出为HTTP_SESSION_TOKEN 解决了这个问题。谢谢! 您不使用标准 Django 会话应用程序的任何原因,该应用程序使用 cookie 而不是标头来传递会话 ID。这似乎更安全,因为您可以指定仅在安全连接等中使用 cookie(不是 100% 万无一失,但至少是这样) 我最初使用 Django 作为原生应用程序的 API 后端,所以这是显而易见的事情。从那以后,我转向构建 Web 客户端,但担心 cookie 的 CSRF 问题,我目前的方法运行良好,所以我保留了它:) 如果您正在制作 API,我建议您使用令牌与会话 ID 的概念。我喜欢使用内置令牌身份验证的 DRF 开发 API - django-rest-framework.org/api-guide/authentication/… 感谢您的提示。尽管名称为Session-Token,但它的价值是在30 天的生命周期内生成的,据我所知,从阅读该文档中可以看出它的工作原理是一样的。谢谢!

以上是关于对 Django 的请求中缺少自定义标头的主要内容,如果未能解决你的问题,请参考以下文章

如何访问 Django Rest Framework 上的自定义 HTTP 请求标头?

transformResponse 标头参数 ($resource) 中缺少自定义响应的标头

在 RSpec 请求规范中使用 Capybara 时设置自定义请求标头的最佳方法是啥?

使用 Spark SQL 流时缺少 Avro 自定义标头

对 PHP API 的 Axios GET 请求不适用于自定义标头

Django-Rest-Framework 系统检查自定义 HTTP 标头(应用程序 - 令牌)