Fom*_*aut 7 django nginx docker
在生产中,我使用链 Django - UWSGI - Docker - Nxing。UWSGI使用50012端口,Ngxin配置为:
proxy_pass http://localhost:50012;
Run Code Online (Sandbox Code Playgroud)
Django 进程认为它的主机localhost:50012
不是 Nginx 监听的域。所以当函数build_absolute_uri
被调用时,localhost:50012
不是我的域。有没有办法让 Django 在build_absolute_uri
被调用时使用自定义主机名?
注意:在某些build_absolute_uri
隐式调用的库中(如social-django
或 example),因此在我的情况下避免使用此函数不是解决方案。
Pau*_*ine 10
当用于访问代理的公共主机名与应用程序服务器的内部主机名不同时,除非代理传递此信息,否则 Django 无法知道原始请求中使用了哪个主机名。
来自MDN:
X-Forwarded-Host (XFH) 标头是事实上的标准标头,用于在 Host HTTP 请求标头中标识客户端请求的原始主机。
反向代理(负载均衡器、CDN)的主机名和端口可能与处理请求的源服务器不同,在这种情况下,X-Forwarded-Host 标头可用于确定最初使用的是哪个主机。
你应该做两件事:
X-Forwarded-Host
标头传递USE_X_FORWARDED_HOST
在设置中开启SECURE_PROXY_SSL_HEADER
一个有意义的值并设置服务器发送相应的标头当USE_X_FORWARDED_HOST
设置为True
in 时settings.py
, HttpRequest.build_absolute_uri
使用X-Forwarded-Host
标题而不是request.META['HTTP_HOST']
or request.META['SERVER_NAME']
。
我不会深入研究代理设置部分(因为它与专业网络管理相关,而不是与本站点范围内的编程相关),但对于 nginx,它应该是这样的:
location / {
...
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...
proxy_pass http://upstream:port;
}
Run Code Online (Sandbox Code Playgroud)
可能是最好的解决方案,因为它是完全动态的,如果将来公共方案/主机名发生变化,您无需更改任何内容。
如果内部和外部的方案也不同,你可能要设置SECURE_PROXY_SSL_HEADER
在settings.py
来是这样的:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Run Code Online (Sandbox Code Playgroud)
然后将以下内容添加到服务器配置中:
proxy_set_header X-Forwarded-Proto https;
Run Code Online (Sandbox Code Playgroud)
假设您的公共主机名是“host.example.com”:您可以将这样的行添加到您的/etc/hosts
(在 Windows 上%windir%\System32\drivers\etc\hosts
):
127.0.0.1 host.example.com
Run Code Online (Sandbox Code Playgroud)
现在您可以在 nginx 配置中使用主机名:
proxy_pass http://host.example.com:port;
Run Code Online (Sandbox Code Playgroud)
当内部和外部方案也不同(外部 https、内部 http)时,您可能需要SECURE_PROXY_SSL_HEADER
按照第一个解决方案中的描述进行设置。
每次公共主机名更改时,您都必须更新配置,但我想这对于小型项目来说是可以的。
归档时间: |
|
查看次数: |
1094 次 |
最近记录: |