gpt4 book ai didi

django - 带有 Nginx 的 Django 的 build_absolute_uri 中的 localhost

转载 作者:行者123 更新时间:2023-12-02 18:02:48 28 4
gpt4 key购买 nike

在生产中,我使用链 Django - UWSGI - Docker - Nxing。 UWSGI 使用 50012 端口,Ngxin 配置为:

proxy_pass http://localhost:50012;

Django进程认为它的主机是 localhost:50012而不是 Nginx 监听的域。所以当函数 build_absolute_uri被称为有 localhost:50012而不是我的域。有没有办法让 Django 在 build_absolute_uri 时使用自定义主机名?叫做?

通知 : 在一些图书馆 build_absolute_uri隐式调用(如 social-django 或示例),因此在我的情况下避免使用此功能不是解决方案。

最佳答案

问题
当您用于访问代理的公共(public)主机名与应用程序服务器的内部主机名不同时,Django 无法知道原始请求中使用了哪个主机名,除非代理正在传递此信息。
可能的解决方案
1)设置代理传递原始主机
来自 MDN :

The X-Forwarded-Host (XFH) header is a de-facto standard header for identifying the original host requested by the client in the Host HTTP request header.

Host names and ports of reverse proxies (load balancers, CDNs) may differ from the origin server handling the request, in that case the X-Forwarded-Host header is useful to determine which Host was originally used.


你应该做两件事:
  • 确保 Django 前面的所有代理都通过 X-Forwarded-Host标题
  • 打开USE_X_FORWARDED_HOST在设置
  • 如果内部和外部方案也不同,设置SECURE_PROXY_SSL_HEADER设置为一个有意义的值并设置服务器发送相应的头

  • USE_X_FORWARDED_HOST设置为 Truesettings.py , HttpRequest.build_absolute_uri使用 X-Forwarded-Host标题而不是 request.META['HTTP_HOST']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;
    }
    可能是最好的解决方案,因为它是完全动态的,如果将来公共(public)方案/主机名发生变化,您不必更改任何内容。
    如果内部和外部方案也不同,您可能需要设置 SECURE_PROXY_SSL_HEADERsettings.py像这样:
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    然后将以下内容添加到服务器配置中:
    proxy_set_header X-Forwarded-Proto https;
    2)公共(public)服务器和私有(private)服务器使用相同的主机名
    假设您的公共(public)主机名是“host.example.com”:您可以在 /etc/hosts 中添加这样的一行。 (在 Windows %windir%\System32\drivers\etc\hosts 上):
    127.0.0.1    host.example.com
    现在您可以在 nginx 配置中使用主机名:
    proxy_pass http://host.example.com:port;
    当内部和外部方案也不同时(外部 https、内部 http),您可能需要设置 SECURE_PROXY_SSL_HEADER如第一个解决方案中所述。
    每次公共(public)主机名更改时,您都必须更新配置,但我想这对于小型项目来说是可以的。

    关于django - 带有 Nginx 的 Django 的 build_absolute_uri 中的 localhost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58044582/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com