我将 Nginx 设置为 uWSGI 应用程序(Django 应用程序)的反向代理。由于 Django 应用程序托管的内容的性质,URL 有时很长。真的很长。因此,HTTPReferer
标头有时也会很长。
问题就在这里。如果客户端收到的 超过 1128 字节(通过反复试验发现),Nginx 会将其丢弃Referer
。任何小于或等于 1128 字节的内容都会被传递到上游服务器。所有大于 1128 字节的内容都会被丢弃。这是一个问题,因为 Django 的 CSRF 保护机制需要完整的Referer
。
这是我的 Nginx 配置文件的相关部分:
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
我查看了 Nginx 文档,但找不到控制客户端标头最大长度的设置。我感到很沮丧,甚至开始研究 Nginx 的源代码,但也没找到任何有用的信息。
我需要做什么才能让 Nginx 将Referer
未修改的内容传递给上游服务器?
版本信息
- Ubuntu 14.04 服务器 64 位
- nginx/1.4.6(Ubuntu)
- uWSGI 1.9.17.1-debian
- Django 1.7.0
答案1
Xavier 的回答随后的讨论让我找到了这个问题的真正原因:uWSGI。看来 uWSGI 正在剥离标头:
[WARNING] unable to add HTTP_REFERER
解决方案非常简单 - 在启动 uWSGI 时,我只需包含以下选项:
--buffer-size 8192
现在所有标头都已传到 Django,并且 CSRF 验证成功。
答案2
Nginx 头读取大小由两个指令控制:
client_header_buffer_size [buffer_size]
这是大多数情况下都适用的默认缓冲区large_client_header_buffers [count] [buffer_size]
如果缓冲区容量不够,则根据需要分配额外的缓冲区client_header_buffer_size
。您必须根据您的情况定制最后一个指令,并确保大于buffer_size
请求中传递的任何行(标头 + 带有 HTTP 方法和 HTTP 版本的 URL)。