我试图重定向所有不安全的HTTP请求在我的网站(例如http://www.example.com)到HTTPS (https://www.example.com)。我如何在.htaccess文件中做到这一点?

我用的是PHP。


当前回答

我尝试了所有我能在互联网上找到的。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服务器

其他回答

最佳解决方案取决于您的需求。这是对之前发布的答案的总结,并添加了一些上下文。

如果你使用Apache web服务器并且可以更改其配置,请参考Apache文档:

<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]

但如果你在这个方向上改变了主意,要小心。浏览器会记住它很长一段时间,不会检查它是否改变了。

根据web服务器配置,您可能不需要第一行RewriteEngine On。

如果你在寻找一个PHP解决方案,看看$_SERVER数组和header函数:

if (!$_SERVER['HTTPS']) {
    header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); 
} 

Apache文档不建议使用重写:

要重定向http url到https,请执行以下操作: < VirtualHost *: 80 > ServerName www.example.com 重定向/ https://www.example.com/ < /虚拟主机> < VirtualHost *: 443 > ServerName www.example.com #……SSL配置在这里 < /虚拟主机>

这段代码应该放在主服务器配置文件中,而不是像问题中要求的那样放在.htaccess中。

这篇文章可能是在问题被提出和回答之后才出现的,但似乎是目前的做法。

在.htaccess文件中添加以下代码:

Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^ https://[your domain name]%{REQUEST_URI} [R,L]

其中[您的域名]是您网站的域名。

你也可以重定向特定的文件夹从你的域名通过替换上面的最后一行代码:

RewriteRule ^ https://[your domain name]/[directory name]%{REQUEST_URI} [R,L]

如果你正在使用亚马逊Web服务弹性负载均衡器,它接受https流量并通过http将其路由到你的服务器,这里描述了将所有http流量重定向到https的正确方法:https://aws.amazon.com/premiumsupport/knowledge-center/redirect-http-https-elb

使用X-Forwarded-Proto报头(包含http或https),它总是包含在来自负载均衡器的http请求中,如下所述: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流量。

以上内容仅适用于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();
}