我有一个应用程序,它是跨多个域的服务器(每个域都自定义应用程序的外观)。
此外,还有一个常见域名,该域名有多个子域名,以显示与上述相同的数据。
因此 -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)重定向正常工作,您可能想要更改它们。即更改
R
为R=301
。