使用.htaccess正确切换HTTP和HTTPS

23
我们有一个购物网站,它托管在共享主机上(Mediatemple Gridserver)。 网站的某些部分需要使用HTTPS(结账等),但其余部分应该使用HTTP。
请问有人知道如何始终强制特定URL正确使用HTTP / HTTPS吗? 我们曾经让它以各种状态工作过,但是我们无法使请求应该在HTTP上但使用HTTPS请求的页面正确切换回来。
我在Stack Overflow上查看了一下,但没有找到合适的答案。

这必须使用htaccess吗?该网站使用什么编程语言? - random
你想通过https来防止什么? - Chris Wesseling
6个回答

40

在WordPress中,我使用类似于以下代码来管理我的管理文件夹:

#redirect all https traffic to http, unless it is pointed at /checkout
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/checkout/?.*$
RewriteRule ^(.*)$ http://mydomain.com/$1 [R=301,L]

RewriteCond %{HTTP:X-Forwarded-SSL} !on

The RewriteCond %{HTTPS} on 部分可能不适用于所有Web服务器。例如,我的Web主机需要 RewriteCond %{HTTP:X-Forwarded-SSL} on

如果你想强制反转,请尝试:

#redirect all http traffic to https, if it is pointed at /checkout
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/checkout/?.*$
RewriteRule ^(.*)$ https://mydomain.com/$1 [R=301,L]

如果你想要一些其他的实现方式,可以查看askapache


我在我的服务器上检查了代码,使用上面列出的两个块,没有重定向循环问题,一切正常。 - Curtis Tasker
+1。非常好的答案。在我的情况下需要使用RewriteCond %{HTTP:X-Forwarded-SSL} on,因为我正在使用RackSpace的云网站。 - Luke Stevenson
2
@wilmoore的建议使用%{SERVER_NAME}将会非常有用。 - antitoxic
3
为让它运作,我必须使用这个检查:RewriteCond %{HTTP:X-Forwarded-Proto} !https - gregn3

16

这应该适用于几乎所有情况,并且应该在您的实际虚拟主机或.htaccess文件中起作用:

RewriteEngine on
RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^(.*)$ https://%{SERVER_NAME}/%{REQUEST_URI} [R=301,L]

(不要忘记在 %{REQUEST_URI} 前面加上斜杠,因为这可能会允许传递端口号,这是危险的)


1
您的答案虽然优雅,但有一个小错误。最后一行应该在SERVER_NAME后面加上斜杠(/),否则www.test.com/dir会被重定向到http://www.test.comdir。 - Juhani
@wilmoore:当选项放置在服务器配置文件中时,这是正确的,因为重写引擎可以挂钩URL到文件名的转换。然而,当放置在每个目录配置文件中时,URI已经通过重写引擎打入路径名。重写引擎通过剥离目录前缀来处理此操作,这最终会删除前面的'/'并匹配结果。 - outis
@wilmoore:实际上,在“%{REQUEST_URI}”之前没有“/”也是可以的,因为它保存了原始请求URI,并且不会被重写引擎更新。我试图指出,“$1”在目录上下文中不正确的原因是Juhani所说的。因此,你的第一个更改不仅使意图更清晰,而且还纠正了Juhani提到的错误。如果没有“%{REQUEST_URI}”,你必须使用RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]。很抱歉我的评论造成了一些困惑。 - outis
@outis,谢谢...我已经有一段时间没有处理Apache服务器了,所以我无法进行测试。感谢您的保证。 - Wil Moore III
最好/更安全的做法是使用“RewriteCond %{HTTPS} off”而不是“RewriteCond %{SERVER_PORT} ^80$”(就像其他答案中所述)。 - Malachi
显示剩余2条评论

6
RewriteEngine on
RewriteCond %{HTTPS} off [OR] 
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{SERVER_NAME}/%{REQUEST_URI} [R=301,L]

我在负载均衡器后面遇到了一些问题,以下是我解决的方法。


2
这真的能有效吗?它把我扔进了一个重定向循环中。如果你有负载均衡器,HTTPS 将不会被设置,第一个 RewriteCond 将会被满足。如果没有,第二个 RewriteCond 将会被满足。因此,每次都会再次重定向。我通过使用(另一个答案)[https://dev59.com/a18d5IYBdhLWcg3wnzRz#26623196]来解决它,基本上是相同的东西,但没有`[OR]`——只有在 HTTPS 关闭且 HTTP:X-Forwarded-Proto 不是 https 的情况下才进行重定向。 - Džuris

2
对我来说,这个方法有效(我在WordPress网站上使用它并将其重定向到HTTPS)。您需要在RewriteEngine和RewriteBase行后面添加条件和规则行:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# I added these two lines for redirect to HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://www.yoursite.com/$1 [R=301,L]
# (end of custom modifications)

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress`

请看条件 RewriteCond %{HTTP:X-Forwarded-Proto} !https - 只有这个适用于我的服务器托管。 (我也尝试了RewriteCond %{SERVER_PORT} !^443$ 或者 RewriteCond %{HTTPS} off,但是没有成功。)

1
此答案所述,修复您的应用程序以在需要时使用https://链接。不要依赖自动重定向,否则如果您没有将链接/表单提供给https://,这可能会让您产生虚假的安全感,并且也很难检测到此类错误(这也可能是漏洞)。使用mod_rewrite可以自动使其更难检测到此类错误。

0

我认为应该是:

RewriteCond %{HTTPS}  =on
^/checkout(.*) http://shoppingsite.com/checkout$1 [R]

请查看mod_rewrite文档。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接