如何将所有 HTTP 请求重定向到 HTTPS
Posted
技术标签:
【中文标题】如何将所有 HTTP 请求重定向到 HTTPS【英文标题】:How to redirect all HTTP requests to HTTPS 【发布时间】:2011-05-04 06:00:35 【问题描述】:我正在尝试将我网站上的所有不安全 HTTP 请求(例如 http://www.example.com
)重定向到 HTTPS (https://www.example.com
)。如何在 .htaccess 文件中执行此操作?
顺便说一句,我正在使用 PHP。
【问题讨论】:
您可以(并且应该)通过您的httpd
执行此操作,而不是使用 php。
@jnpcl,虽然我同意 httpd 解决方案比基于 PHP 的解决方案更好,但我认为系统重定向通常不是一个好习惯。如果您想始终将您的用户重定向到 HTTPS,请从“入口点”(指向您网站的第一个链接)将他们发送到那里,不要半途而废,这可能会泄露一些您认为的数据受保护(如果您没有注意到瞬时重定向)。
@Bruno:我更多地考虑了重复的http请求、丢失查询字符串的可能性以及用户手动输入http://
的可能性
@jnpcl 这确实是一个好点。我只是建议,虽然人们倾向于要求这种重定向来提高他们网站的安全性,但通常,它实际上并没有改善它(因为它不会阻止相同的请求首先通过纯 HTTP) .
@outis:您发布的第一个链接是this question。
【参考方案1】:
Apache docs 建议不要使用重写:
要将
http
URL 重定向到https
,请执行以下操作:<VirtualHost *:80> ServerName www.example.com Redirect / https://www.example.com/ </VirtualHost> <VirtualHost *:443> ServerName www.example.com # ... SSL configuration goes here </VirtualHost>
这个sn-p应该进入主服务器配置文件,不进入.htaccess
问题中询问。
这篇文章可能是在问题被提出和回答后才出现的,但似乎是当前的发展方向。
【讨论】:
在哪里可以找到主服务器配置文件 我喜欢不必复制 *:80 和 *:443 的 VirutalHost 记录,Chrome 对挂锁很满意,但是 Firefox 说“此页面的某些部分不确定(例如图像)。如何解决这个问题??support.mozilla.org/en-US/kb/mixed-content-blocking-firefox【参考方案2】:更新:虽然这个答案在几年前就被接受了,但请注意它的方法是 Apache 文档中的now recommended against。请改用Redirect
。见this answer。
RewriteEngine On
RewriteCond %HTTPS !on
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI
【讨论】:
对于新手,这将重定向example.com
,http://example.com
到 https://example.com
和 www.example.com
,http://www.example.com
到 http://www.example.com
到 https://www.example.com
- 请参阅删除 www 的其他答案
你的措辞太强烈了,这是对这个答案的诅咒。在该链接中,Apache 说:“如果出于某种原因,您仍想使用 mod_rewrite
... 您可以使用”。当然,如果您无权访问服务器配置(99% 的用户),那么这个答案很好。【参考方案3】:
我建议使用 301 重定向:
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R=301,L]
【讨论】:
【参考方案4】:正如我在this question 中所说,我建议您避免盲目地将所有 HTTP 请求重定向到其 HTTPS 等效项,因为这可能会导致您对安全性产生错误印象。相反,您可能应该将 HTTP 站点的“根”重定向到 HTTPS 站点的根并从那里链接到 HTTPS。
问题在于,如果 HTTPS 站点上的某些链接或表单使客户端向 HTTP 站点发送请求,则在重定向之前其内容将是可见的。
例如,如果您通过 HTTPS 提供的某个页面的表单显示为 <form action="http://example.com/doSomething">
,并且发送了一些不应以明文形式发送的数据,则浏览器将首先发送完整的请求(包括实体,如果它是POST) 首先到 HTTP 站点。重定向将立即发送到浏览器,并且由于大量用户禁用或忽略警告,因此很可能会被忽略。
当然,错误地提供了应该指向 HTTPS 站点但最终指向 HTTP 站点的链接,一旦您在与 HTTPS 相同的 IP 地址上的 HTTP 端口上侦听某些内容,则可能会导致问题地点。但是,我认为将这两个站点保持为“镜像”只会增加出错的机会,因为您可能倾向于假设它会通过将用户重定向到 HTTPS 来自动更正,但通常为时已晚。 (this question.也有类似讨论)
【讨论】:
【参考方案5】:这是它有效的 html 重定向方法,但不是最好的。
<meta http-equiv="Refresh" content="0;URL=https://www.example.com" />
PHP 方法
<?php
function redirectTohttps()
if ($_SERVER['HTTPS']!="on")
$redirect= "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("Location:$redirect");
?>
.htaccess 方法
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI
复制自: www.letuslook.org
【讨论】:
我喜欢你的 PHP 方法。不错【参考方案6】:我发现域上 https 和 www 的最佳方式是
RewriteCond %HTTPS off
RewriteCond %HTTPS_HOST !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
【讨论】:
Apache htaccess 中没有可用的HTTPS_HOST
变量。只能使用HTTP_HOST
。此外,您可以在第一个条件的末尾添加 [OR]
以使其整体更加灵活,因为现在它只能重定向非 ssl 非 www 请求。【参考方案7】:
我喜欢这种从 http 重定向到 https 的方法。因为我不需要为每个站点都编辑它。
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R,L]
【讨论】:
【参考方案8】:最佳解决方案取决于您的要求。这是先前发布的答案的摘要,并添加了一些上下文。
如果您使用 Apache Web 服务器并且可以更改其配置,请按照Apache documentation:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost>
但您还询问是否可以在 .htaccess
文件中执行此操作。在这种情况下,您可以使用 Apache 的 RewriteEngine:
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [L]
如果一切正常并且您希望浏览器记住此重定向,您可以将最后一行更改为:
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R=301,L]
但是,如果您可能在此重定向上改变主意,请小心。浏览器会记住它很长时间,并且不会检查它是否改变了。
根据网络服务器配置,您可能不需要第一行 RewriteEngine On
。
如果您正在寻找 PHP 解决方案,请查看 $_SERVER array 和 header function:
if (!$_SERVER['HTTPS'])
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
【讨论】:
【参考方案9】:在您的 .htaccess 文件中使用以下代码会自动将访问者重定向到您网站的 HTTPS 版本:
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule ^(.*)$ https://%HTTP_HOST%REQUEST_URI [L,R=301]
如果您有一个现有的 .htaccess 文件:
不要重复 RewriteEngine On。
确保以 RewriteCond 和 RewriteRule 开头的行紧跟在已经存在的 RewriteEngine On 之后。
【讨论】:
【参考方案10】:这是根据 GoDaddy.com 使用 .htaccess 将 HTTP 重定向到 HTTPS 的正确方法。第一行代码是不言自明的。第二行代码检查 HTTPS 是否关闭,如果是,则通过运行第三行代码将 HTTP 重定向到 HTTPS,否则忽略第三行代码。
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule ^(.*)$ https://%HTTP_HOST%REQUEST_URI [L,R=301]
https://www.godaddy.com/help/redirect-http-to-https-automatically-8828
【讨论】:
【参考方案11】:将以下代码添加到 .htaccess 文件中:
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %SERVER_PORT !=443
RewriteRule ^ https://[your domain name]%REQUEST_URI [R,L]
[your domain name] 是您网站的域名。
您还可以通过将上面代码的最后一行替换为以下代码来重定向特定文件夹:
RewriteRule ^ https://[your domain name]/[directory name]%REQUEST_URI [R,L]
【讨论】:
【参考方案12】:按照上面解释的一切进行重定向。只需将“HTTP 严格传输安全”添加到您的标题中。这样可以避免中间人攻击。
编辑您的 apache 配置文件(例如 /etc/apache2/sites-enabled/website.conf 和 /etc/apache2/httpd.conf)并将以下内容添加到您的 VirtualHost:
# Optionally load the headers module:
LoadModule headers_module modules/mod_headers.so
<VirtualHost 67.89.123.45:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
</VirtualHost>
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
【讨论】:
【参考方案13】:要将所有 http
请求重定向到 https
,您可以使用:
RewriteEngine on
RewriteCond %HTTPS off
RewriteRule ^ https://%HTTP_HOST%REQUEST_URI [NE,L,R]
如果未启用 mod-rewrite 并且您使用的是 apache 2.4,您还可以在 if
指令中使用 Redirect
将 http
请求重定向到 https
。
Apache 2.4。
<if "%HTTPS !~ /on/">
Redirect / https://www.example.com/
</if>
【讨论】:
【参考方案14】:如果您无法直接访问您网站的 apache 配置,而许多托管平台仍以这种方式受到限制,那么我实际上建议您采用两步法。 Apache 自己记录您应该首先使用他们的配置选项而不是 mod_rewrite for HTTP to HTTPS 的原因。
首先,如上所述,您将设置您的 .htaccess mod_rewrite 规则:
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule ^ https://%HTTP_HOST%REQUEST_URI [R=301,L]
然后,在您的 PHP 文件中(您需要在适合您情况的任何地方执行此操作,一些网站将通过单个 PHP 文件汇集所有请求,其他网站则根据他们的需要和请求):
<?php if ($_SERVER['HTTPS'] != 'on') exit(1); ?>
上述代码需要在任何可能在不安全环境中暴露安全数据的代码之前运行。因此,您的网站通过 HTACCESS 和 mod_rewrite 使用自动重定向,而您的脚本确保在不通过 HTTPS 访问时不提供输出。
我想大多数人都不会这样想,因此 Apache 建议您尽可能不要使用这种方法。但是,它只需要在开发端进行额外检查,以确保您的用户数据是安全的。希望这可以帮助其他可能由于我们的托管服务限制而不得不考虑使用非推荐方法的人。
【讨论】:
【参考方案15】:除非您需要 mod_rewrite 来处理其他事情,否则使用 Apache 核心 IF 指令更干净、更快:
<If "%HTTPS == 'off'">
Redirect permanent / https://yoursite.com/
</If>
您可以向 IF 指令添加更多条件,例如确保没有 www 前缀的单个规范域:
<If "req('Host') != 'myonetruesite.com' || %HTTPS == 'off'">
Redirect permanent / https://myonetruesite.com/
</If>
对所有事情都使用 mod_rewrite 有很多熟悉惯性,但看看这是否适合你。
更多信息:https://httpd.apache.org/docs/2.4/mod/core.html#if
要查看它的实际效果(尝试不使用 www. 或 https://,或使用 .net 而不是 .com):https://nohodental.com/(我正在开发的网站)。
【讨论】:
【参考方案16】: Redirect 301 / https://example.com/
(当上述答案均无效时为我工作)
奖金:
ServerAlias www.example.com example.com
(固定 https://www.example.com 未找到)
【讨论】:
【参考方案17】:将此代码交给您的 .htaccess 文件 Redirect HTTP to HTTPS automatically
RewriteEngine On
RewriteCond %HTTPS off
RewriteRule ^(.*)$ https://%HTTP_HOST%REQUEST_URI [L,R=301]
【讨论】:
【参考方案18】:以上内容仅适用于 Apache 服务器。如果在tomcat上运行PHP呢?
所以你可以使用PHP代码,无论是Apache/tomcat/nginx等...
if (!((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')))
$redirect = 'https://' . str_replace($_SERVER['SERVER_PORT'], 8443, $_SERVER['HTTP_HOST']) . $_SERVER['REQUEST_URI'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $redirect);
exit();
【讨论】:
【参考方案19】:通过 .htaccess 这会有所帮助。
RewriteEngine On
RewriteBase /
RewriteCond %HTTP_HOST ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %HTTPS !=on
RewriteRule ^/?(.*) https://%SERVER_NAME/$1 [R,L]
另外,请参阅此以获取更多详细信息。 How To Redirect Http To Https?
【讨论】:
【参考方案20】:我找到了一种方法,可以强制我网站的所有页面从 http 重定向到适用于我的 https 上的模拟页面。
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R=301,L]
【讨论】:
【参考方案21】:这会将所有 URL 重定向到 https 和 www
RewriteCond %HTTPS off [OR]
RewriteCond %HTTPS_HOST !^www.example.com$ [NC,OR]
RewriteCond %HTTP_HOST !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
【讨论】:
默认情况下,在 Apachehtaccess
中无法访问 HTTPS_HOST
变量。您只能使用HTTP_HOST
。此外,您的第三个条件是多余的,因为第一个条件已经过滤掉了非 ssl 请求。【参考方案22】:
如果您想从 tomcat 服务器执行此操作,请按照以下步骤操作
在独立的 Apache Tomcat (8.5.x) HTTP 服务器中,如何配置它,如果用户键入 www.domain.com,他们将自动转发到 https(www.domain.com) 站点。
在 [Tomcat_base]/conf/web.xml 结束标记前包含以下内容的两步法
step 1:
<security-constraint>
<web-resource-collection>
<web-resource-name>HTTPSOnly</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
并设置 [Tomcat_base]/conf/server.xml 连接器设置:
step 2:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="443"/>
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="[keystorelocation]" type="RSA" />
</SSLHostConfig>
</Connector>
注意:如果您已经进行了 https 配置并尝试重定向,请仅执行第 1 步。
【讨论】:
【参考方案23】:您不仅可以在 .htaccess 文件中执行此操作,还应该在此期间执行此操作。在实施此重定向后,您还需要按照步骤here 将您的网站列在 HSTS 预加载列表中,这样对您网站的不安全 http 版本的任何请求都不会通过用户代理。相反,用户代理检查请求的 URI 与仅 https 网站的烘焙列表,如果请求的 URI 在该列表中,则在将请求传输到服务器之前将协议从 http 更改为 https。因此,不安全的请求永远不会出现,也永远不会到达服务器。最终,当互联网切换到 https 时,将不再需要 HSTS 预加载列表。在那之前,每个网站都应该使用它。
为了执行重定向,我们需要启用重写引擎,然后将所有流量从 http 端口 80 重定向到 https。
RewriteEngine On
RewriteCond %SERVER_PORT 80
RewriteRule ^(.*)$ https://yourwebsite.tld/$1 [L,R=301]
【讨论】:
【参考方案24】:我尝试了所有可以在 Internet 上找到的 .htaccess
配置,但没有一个有效。
然后,我意识到Apache 不鼓励使用mod_rewrite
。
我的解决方案是在以下文件夹下编辑 apache 配置文件:
/etc/apache2/sites-enabled
您将拥有一个名为000-default.conf
的强制文件和一个名为000-default-le-ssl.conf
的ssl 配置文件(如果您已从letsencrypt/certbot 安装了ssl 证书)。但是,根据您在设置站点时提供的文件名,这些文件的名称可能会有所不同。
在000-default.conf
中,我在<VirtualHost *:80>
中将以下内容编辑为:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
在000-default-le-ssl.conf
中,我在<VirtualHost *:80>
中将以下内容编辑为:
<VirtualHost *:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
不需要其他重定向。
保存文件然后使用sudo service apache2 restart
重启apache服务器
【讨论】:
【参考方案25】:在考虑不带 www 和带 www 的情况下进行大量尝试后,这可行
RewriteEngine on
RewriteCond %HTTPS off
RewriteCond %HTTP_HOST (www\.)?yourdomain.com
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [L,R=301]
【讨论】:
【参考方案26】:如果您使用的是 Apache,mod_rewrite 是最简单的解决方案,并且有很多在线文档如何做到这一点。例如:http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
【讨论】:
【参考方案27】:这个问题的另一个优势是负载均衡器开始发挥作用。
情况如下: - 从浏览器到负载均衡器并返回的流量是(应该是)HTTPS - 负载均衡器和实际 WebServer 之间的流量是 HTTP。
因此,PHP 或 Apache 中的所有服务器请求变量都表明连接只是 HTTP。并且Server上的HTTP和HTTPS目录是一样的。
已批准答案中的 RewriteCondition 不起作用。 它要么给出一个循环,要么就是不起作用。
问题是:如何让它在负载均衡器上工作。
(或者负载均衡器配置错误。这是我所希望的,因为这样我可以将问题转移到 WebHosting 公司 :-))
【讨论】:
【参考方案28】:如果您使用的是接受 https 流量并使用 http 将其路由到您的服务器的 Amazon Web Services 弹性负载均衡器,则此处描述了将所有 http 流量重定向到 https 的正确方法:https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb
使用始终包含在来自负载均衡器的 http 请求中的 X-Forwarded-Proto 标头(包含 http 或 https),如下所述:https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
在 httpd.conf 文件中:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto =http
RewriteRule .* https://%HTTP:Host%REQUEST_URI [L,R=permanent]
</VirtualHost>
或者在你的根 .htaccess 文件中:
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto =http
RewriteRule .* https://%HTTP:Host%REQUEST_URI [L,R=permanent]
奖励:它不会尝试在本地开发机器上重定向 http 流量。
【讨论】:
【参考方案29】:它对我有用:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %HTTPS !on
RewriteRule ^(.*)$ https://%HTTP_HOST%REQUEST_URI [L,R=301]
</IfModule>
例如,http://server/foo?email=someone%40example.com 可以正常重定向而不会出现任何问题。 位于网站根文件夹中的 .htaccess 文件(例如名为 public_html)。 可以使用 RewriteCond %SERVER_PORT !^443$ 而不是 RewriteCond %HTTPS !on
【讨论】:
以上是关于如何将所有 HTTP 请求重定向到 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章
将所有 HTTP 和 HTTPS 请求重定向到单个 HTTPS URL
如何使用 aws 弹性负载均衡器将 http 请求强制重定向到独立乘客中的 https?