htaccess 文件对不同的域执行特定的规则

htaccess 文件对不同的域执行特定的规则

我有一个应用程序,它是跨多个域的服务器(每个域都自定义应用程序的外观)。

此外,还有一个常见域名,该域名有多个子域名,以显示与上述相同的数据。

因此 -www.apples.com看起来与apples.efruit.co.uk

和 -www.bananas.co.uk看起来与bananas.efruit.co.uk

ETC

现在,我有一个用于 efruit.co.uk 域的通配符 SSL,因此我想使用 htaccess 文件强制所有 efruit.co.uk 请求使用 https(如果尚未这样做)。

所有其他域名都没有 SSL,因此它们需要使用 http 来避免浏览器警告 - 再次来自 htaccess 文件。

我还想使用 htaccess 文件,这样如果有人输入 www.apples.efruit.co.uk,它会重写为 apples.efruit.co.uk(如上所述通过 https)。但是,如果它不是 efruit.co.uk 域,则 www. 也可以。

最后,我得到了 codeigniter 的标准且有据可查的重写规则,以使 url 更漂亮。

这是我目前所拥有的。

Options +FollowSymlinks
RewriteEngine On

RewriteCond %{REQUEST_URI} !(health_check\.php)$
RewriteCond %{HTTP_HOST} ^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

RewriteCond %{HTTP_HOST} !^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R,L]

RewriteCond %{HTTP_HOST} ^www\.([^\.]*)\.efruit\.co\.uk$
RewriteRule (.*) https://%1.efruit.co.uk$1 [R,L]

# block hidden directories
RewriteRule "(^|/)\." - [F]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]

不过,唯一可行的办法是强制 efruit.co.uk 域名通过 https 提供服务。

答案1

您似乎位于 SSL 代理后面(?),因此使用X-Forwarded-Proto请求标头,而不是HTTPS服务器变量。

RewriteCond %{REQUEST_URI} !(health_check\.php)$
RewriteCond %{HTTP_HOST} ^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

虽然您声明此部分“有效”(“强制efruit.co.uk通过 https 提供域服务”),但这不会重定向主裸域,并且它还会保留 www 子域(如果请求中存在)——您应该先将其剥离以避免二次重定向。因此,需要更改这些指令的顺序。

您也不需要捕获组(即带括号的子模式),除非您打算将其用作反向引用 - 但您似乎并不打算这样做。

所有其他域名都没有 SSL,因此它们需要使用 http 来避免浏览器警告 - 再次来自 htaccess 文件。

您无法发出 HTTPS 到 HTTP 重定向,.htaccess以避免这些其他域上的浏览器警告 - 这似乎是您所建议的。因为无效的 SSL 证书浏览器警告发生 .htaccess执行。SSL 握手发生在请求一开始。

RewriteCond %{HTTP_HOST} !^(.*)\.efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R,L]

因此,除非用户接受 SSL 证书警告(他们不应该接受),否则上述操作实际上不会从浏览器执行。

RewriteCond %{HTTP_HOST} ^www\.([^\.]*)\.efruit\.co\.uk$
RewriteRule (.*) https://%1.efruit.co.uk$1 [R,L]

.htaccess会导致无效的重定向,对于除文档根目录之外的任何目录,因为$1反向引用没有斜杠前缀。即使对于文档根目录,您也应该在代换(尽管浏览器会隐式地修复这个问题)。另外,好奇为什么你REQUEST_URI在前两个规则中使用了服务器变量,但在这里却使用了反向引用?

请尝试以下类似操作:

# Prevent any fruther processing when requesting "health_check.php"
# CHECK: Absence of start of string anchor?
RewriteRule health_check\.php$ - [L]

# Remove www sub-subdomain (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.efruit\.co\.uk [NC]
RewriteRule .* https://%1.efruit.co.uk%{REQUEST_URI} [R,L]

# HTTP to HTTPS redirect for the "efruit.co.uk" domain (and subdomains)
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteCond %{HTTP_HOST} ^([^.]+\.)?efruit\.co\.uk [NC]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

# HTTPS to HTTP redirect for none "efruit.co.uk" domains
# Note that the user will still have to click through any browser security warnings
RewriteCond %{HTTP_HOST} !(^|\.)efruit\.co\.uk
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R,L]

其他说明:

  • 在字符类中使用时,无需使用反斜杠转义文字点。
  • 我已经删除了$主机检查中的字符串锚点的末尾,以便捕获包含尾随点的 FQDN。
  • 一旦您确认这些永久(301)重定向正常工作,您可能想要更改它们。即更改RR=301

相关内容