如何在不破坏其他非 www 子域的情况下从 http:// 重定向到 https:// 再到 https://www?

How do I redirect from http:// to https:// to https://www without breaking other subdomains that aren't www?

环境:

Wordpress 运行 在一个 Docker 容器上构建了一个测试管道,首先进入开发(https://dev.example.com),然后进入阶段(https://stage.example.com),最后投入生产 (https://www.example.com).

请注意,Dev 和 Stage 没有 有 "www" 子域,但生产有。

问题:

出于安全原因,我必须设置一个额外的重定向。目前,当用户在没有 SSL 的情况下(即 http://example.com)进入我们的网站时,他们将被重定向到安全子域(即 https://www.example.com)。

但是,为了安全起见,他们需要在 被重定向到安全子域之前点击 https://example.com 。如:

1) http://example.com ->

2) https://example.com ->

3) https://www.example.com

我们必须有 www 作为最终结果,我们必须有额外的重定向(遗憾的是没有回旋余地)。

现在,我遇到的问题是这个重定向和 dev/stage 站点。

我可以使用以下代码从 http://example.com -> https://example.com -> https://www.example.com 获得生产重定向:

<IfModule mod_rewrite.c>
RewriteEngine On
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} example.com$
RewriteRule ^ https://example.com [L,R=301]

# ensure www.
RewriteCond %{HTTP_HOST} !^www\.example.com$ [NC]
RewriteRule ^ https://www.example.com [L,R=301]
</IfModule>

但是当把这段代码搬进去的时候dev/stage他们502死了

我尝试使用下面的代码仅在服务器不是 www 或 dev 或 stage 时重定向到 www,但是从 http://example.comhttps://example.com 的重定向失败了!

<IfModule mod_rewrite.c>
RewriteEngine On
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} example.com$
RewriteRule ^ https://example.com [L,R=301]

# ensure www only if not dev/stage
RewriteCond %{HTTP_HOST} !^(www|dev|stage)\.example.com$ [NC]
RewriteRule ^ https://www.example.com [L,R=301]
</IfModule>

请帮忙!我知道使用如此多的重定向有点过头了,但它们是我收到的要求,我无法更改它们。

非常感谢任何帮助,我在这里查看了许多其他答案,他们提供了帮助,但我无法通过 dev/stage 重定向失败。我卡住了!


我的完整 htaccess 文件:

<IfModule mod_rewrite.c>

 RewriteEngine On
 # ensure https
 RewriteCond %{HTTP:X-Forwarded-Proto} !https
 RewriteCond %{HTTPS} off
 RewriteCond %{HTTP_HOST} (^|\.)example\.com$
 RewriteRule ^/?(.*)$ https://%{HTTP_HOST}/ [R=302]

 # ensure www.
 RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
 RewriteCond %{HTTP_HOST} !^(www|corp-dev|corp-stage)\.example\.com$
 RewriteRule ^/?(.*)$ https://www.example.com/ [R=302]

# link Redirection

RewriteEngine On
RewriteRule ^health\.html$ "/health.html" [END]

RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

你的尝试几乎没问题,我只是做了一些微不足道的调整:

RewriteEngine On
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} (^|\.)example\.com$
RewriteRule ^/?(.*)$ https://%{HTTP_HOST}/ [R=301]

# ensure www.
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} !^(www|dev|stage)\.example\.com$
RewriteRule ^/?(.*)$ https://www.example.com/ [R=301]

一般来说,开始使用 302 重定向进行测试是个好主意,只有在一切正常时才将其更改为 301。这样你就可以在测试时防止缓存问题。

此规则同样适用于 http 服务器主机配置或动态配置文件(“.htaccess”文件)。显然重写模块需要在http服务器内部加载并在http主机中启用。如果您使用动态配置文件,您需要注意它的解释在主机配置中完全启用,并且它位于主机的 DOCUMENT_ROOT 文件夹中。

一般性评论:您应该始终倾向于将此类规则放在 http 服务器主机配置中,而不是使用动态配置文件 (".htaccess")。那些动态配置文件增加了复杂性,通常是意外行为的原因,难以调试并且它们确实减慢了 http 服务器的速度。它们仅在您无法访问真正的 http 服务器主机配置(阅读:非常便宜的服务提供商)或坚持编写自己的规则(这是一个明显的安全噩梦)的应用程序的情况下作为最后的选择提供。

最终为我解决了这个问题:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  RewriteCond %{HTTP_HOST} ^example.com$
  RewriteRule (.*)$ https://example.com/ [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  RewriteCond %{HTTP_HOST} ^www.example.com$
  RewriteRule (.*)$ https://www.example.com/ [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  RewriteCond %{HTTP_HOST} ^dev.example.com$
  RewriteRule (.*)$ https://dev.example.com/ [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} =http
  RewriteCond %{HTTP_HOST} ^stage.example.com$
  RewriteRule (.*)$ https://stage.example.com/ [R=301,L]
</IfModule>

我的 WordPress 站点的“常规设置”选项卡下的站点 URL 设置为 https://www.example.com,这导致其他解决方案出现大量循环。

由于我提到的设置,这对我不起作用,但我会 post 我试过的另一个解决方案,希望它能帮助其他人:

<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect HTTP to HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://example.com/ [R,L]

# Redirect example.com to www.example.com
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^/?(.*) https://www.example.com/ [R,L]
</IfModule>