上下文:我已经编写了一个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?不同。
出了什么问题?如何在生产中访问后端的自定义标题?
答案 0 :(得分:14)
最有可能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的开发服务器不建议用于生产用途,但匹配常见生产服务器的行为会减少部署期间行为更改的表面区域。
如果您有任何自定义标题,则应使用连字符。