【问题标题】:django: disable PREPEND_WWW when using ip address instead of domain namedjango:使用 IP 地址而不是域名时禁用 PREPEND_WWW
【发布时间】:2023-03-25 23:19:01
【问题描述】:

在负载均衡器后面运行的 Django 网站通过使用实例的 IP 地址而不是域名在 /health/ 上发出 HTTP GET 请求来执行健康检查。

如果缺少 www,我会使用 PREPEND_WWW 将 www 添加到域名中。

但是 PREPEND_WWW 也将 www 添加到 IP 地址,这显然是错误的。例如http://www.123.123.123.123/health/

有没有办法防止为 IP 地址添加 www,或者仅在匹配正则表达式列表时添加 www?

或者我应该简单地避免使用 PREPEND_WWW 并使用自定义视图/重定向手动实现重定向?

请注意,我也使用 SECURE_SSL_REDIRECT = True,以防万一这对 www 重定向也有影响。


为了将来参考,我在 Ubuntu 上使用 Apache 和 mod_wsgi,所以我的“服务器级”解决方案是使用 mod_rewrite。

# Edit vhost configuration
sudo vi /etc/apache2/sites-enabled/000-default.conf

# Add redirection to VirtualHost block
<VirtualHost *:80>
    ...
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^domain.com$
    RewriteRule (.*) https://www.domain.com$1 [R=301,L]
    ...

# Enable mod_rewrite and restart
sudo a2enmod rewrite && sudo service apache2 restart

【问题讨论】:

  • 我想说这应该在生产中的 nginx(或其他 Web 服务器)级别上完成。

标签: python django


【解决方案1】:

一般来说,PREPEND_WWW 是一个较少使用的设置,因为它是错误的 - 它不适用于主机名别名、IP 地址甚至 localhost。 这是 Django 上的一个已知问题,看起来无法修复。 以下是relevant ticket的详细信息

就像@makaveli 指出的那样,nginx 或您可能正在使用的任何其他 Web 服务器代理都是进行重定向的正确位置。

但是,如果您绝对必须在代码中执行此操作,这里有一种方法: 您可以做的一件事是,编写您自己的 custom middleware which is derived from CommonMiddleware,它会覆盖 process_request

例如,

must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
    redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''

可能是(伪代码)

must_prepend = False
ip_address_regex = ....
if settings.PREPEND_WWW:
    must_prepend =  host and not re.match(ip_address_regex, host) and not host.startswith('www.')
redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''

当然,这需要经过充分测试,并且您有责任在 CommonMiddleware 实现发生变化时更新此中间件。

【讨论】:

  • 谢谢。我猜想 python/django 解决方案将覆盖 process_request ,您的示例有助于理解它是如何工作的。但是,我会按照建议在服务器级别执行重定向。
猜你喜欢
  • 2017-01-03
  • 1970-01-01
  • 2017-10-12
  • 2018-07-23
  • 2014-08-13
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多