关于php:如何强制用户通过HTTPS而非HTTP访问我的页面?

关于php:如何强制用户通过HTTPS而非HTTP访问我的页面?

How can I force users to access my page over HTTPS instead of HTTP?

我只有一个页面要强制作为HTTPS页面(Apache上的PHP)进行访问。如何在不使整个目录都需要HTTPS的情况下执行此操作?或者,如果您从HTTP页面向HTTPS页面提交表单,它是否通过HTTPS而不是HTTP发送?

这是我的示例:

1
http://www.example.com/some-page.php

我希望只能通过以下方式访问它:

1
https://www.example.com/some-page.php

当然,我可以将指向此页面的所有链接都指向HTTPS版本,但这并不能阻止一些傻瓜故意通过HTTP访问它...

我想到的一件事是在PHP文件的标头中放置一个重定向,以检查它们是否正在访问HTTPS版本:

1
2
3
if($_SERVER["SCRIPT_URI"] =="http://www.example.com/some-page.php"){
  header('Location: https://www.example.com/some-page.php');
}

但这不是正确的方法,对吗?

顺便说一句,请不要关注URL。我知道,如果实际上是一个有购物车等的页面,那么您将以另一种方式进行操作。可以将其视为来自某网站的页面,该网站以一种价格出售一件商品,您在其中键入您的信用卡信息,然后提交给外部网站上的付款网关,以明确地对您的卡进行一次收费。


我以前做过的方式基本上就像您写的一样,但是没有任何硬编码的值:

1
2
3
4
5
if($_SERVER["HTTPS"] !="on")
{
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}

您可以在Apache上使用指令和mod_rewrite来实现:

1
2
3
4
5
<Location /buyCrap.php>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Location>

如果需要,您可以使用正则表达式使位置信息随着时间的推移变得更智能。


您应强制客户端始终使用HTTP Strict Transport Security(HSTS)标头请求HTTPS:

1
2
3
4
5
6
7
8
9
10
11
// Use HTTP Strict Transport Security to force client to use secure connections only
$use_sts = true;

// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
    header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
    // we are in cleartext at the moment, prevent further execution and output
    die();
}

请注意,大多数现代浏览器都支持HSTS,但不是通用浏览器。因此,以上逻辑在用户不支持HTTP的情况下手动重定向用户,无论他们是否支持HTTP,然后设置HSTS标头,以便在可能的情况下由浏览器重定向其他客户端请求。


我刚刚创建了一个.htaccess文件并添加了:

1
2
3
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

很简单!


1
2
3
4
5
6
7
8
9
10
// Force HTTPS for security
if($_SERVER["HTTPS"] !="on") {
    $pageURL ="Location: https://";
    if ($_SERVER["SERVER_PORT"] !="80") {
        $pageURL .= $_SERVER["SERVER_NAME"] .":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    header($pageURL);
}

在负载平衡器后面运行时,必须执行类似的操作。帽子提示https://stackoverflow.com/a/16076965/766172

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function isSecure() {
    return (
        (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
     || $_SERVER['SERVER_PORT'] == 443
     || (
            (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
         || (!empty($_SERVER['HTTP_X_FORWARDED_SSL'])   && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
        )
    );
}

function requireHTTPS() {
    if (!isSecure()) {
        header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], TRUE, 301);
        exit;
    }
}

PHP方式:

1
2
3
4
5
6
7
$is_https=false;
if (isset($_SERVER['HTTPS'])) $is_https=$_SERVER['HTTPS'];
if ($is_https !=="on")
{
    header("Location: https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
    exit(1);
}

Apache mod_rewrite方式:

1
2
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

http://www.besthostratings.com/articles/force-ssl-htaccess.html

有时您可能需要确保用户正在通过安全连接浏览您的站点。始终将用户重定向到安全连接(https://)的简单方法可以通过包含以下行的.htaccess文件来实现:

1
2
3
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

请注意,.htaccess文件应位于网站的主文件夹中。

如果您希望对特定文件夹强制使用HTTPS,则可以使用:

1
2
3
4
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} somefolder
RewriteRule ^(.*)$ https://www.domain.com/somefolder/$1 [R,L]

.htaccess文件应放置在需要强制使用HTTPS的文件夹中。


好吧..现在有很多东西,但是没有人真正完成
"安全"问题。对我来说,使用不安全的东西是荒谬的。

除非您将其用作诱饵。

$ _SERVER传播可以知道某人的意愿进行更改。

就像Sazzad Tushar Khan和thebigjc所说的那样,您也可以使用httaccess来做到这一点,并且这里有很多答案。
只需添加:

1
2
3
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

到.httaccess中所有内容的结尾,就是这样。

仍然,我们不像使用这两个工具那样安全。

其余的很简单。如果缺少属性,即...

1
2
3
4
5
if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}

if(strstr($_SERVER['HTTP_HOST'],"mywebsite.com") === FALSE){// Something is FISHY
}

还要说您已经更新了httaccess文件并检查:

1
2
if($_SERVER["HTTPS"] !=="on"){// Something is fishy
}

您可以检查更多变量,即

HOST_URI(如果要检查是否有静态属性)

HTTP_USER_AGENT(同一会话的不同值)

因此,我的意思是,当答案组合在一起时,不要仅仅满足于一个或另一个。
有关更多的httaccess重写信息,请参阅docs-> http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
一些堆栈->使用.htaccess和mod_rewrite强制SSL / https

获取当前页面的完整URL(PHP)
仅举几例。


使用htaccess

1
2
3
4
5
6
7
8
#if domain has www. and not https://
 RewriteCond %{HTTPS} =off [NC]
  RewriteCond %{HTTP_HOST} ^(?i:www+\.+[^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]

#if domain has not www.
 RewriteCond %{HTTP_HOST} ^([^.]+\.+[^.]+)$
  RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=307]

使用$_SERVER['HTTPS']判断它是否为SSL,如果不是,则重定向到正确的位置。

请记住,显示表单的页面不需要通过HTTPS进行馈送,而最需要它的是发回URL。

编辑:是的,正如下面所指出的,最好将整个过程放在HTTPS中。更加令人放心-我指出,帖子是最关键的部分。另外,您需要注意将所有cookie设置为安全的,因此它们只会通过SSL发送。 mod_rewrite解决方案也很漂亮,我用它来保护自己网站上的许多应用程序。


如果您使用Apache或支持.htaccess文件的LiteSpeed之类的工具,则可以执行以下操作。
如果还没有.htaccess文件,则应在根目录(通常是index.php所在的位置)中创建一个新的.htaccess文件。现在,将这些行添加为.htaccess中的第一个重写规则:

1
2
3
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

对于所有重写规则,您仅需要在.htaccess中使用一次" RewriteEngine On"指令,因此,如果已经有了它,则只需复制第二行和第三行即可。

我希望这有帮助。


仅使用此功能还不够:

1
2
3
4
5
if($_SERVER["HTTPS"] !="on")
{
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}

如果您有任何http内容(例如外部http图像源),则浏览器将检测到可能的威胁。因此,请确保您代码中的所有ref和src均为https


对于使用IIS的用户,在web.config中添加此行将有所帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<httpProtocol>
    <customHeaders>
       
    </customHeaders>
</httpProtocol>
<rewrite>
    <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
              <match url="(.*)" />
              <conditions>
                 
              </conditions>
             
         </rule>
    </rules>
</rewrite>

完整的示例文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
               
             </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions>
                         
                      </conditions>
                     
                 </rule>
            </rules>
       </rewrite>
   </system.webServer>
</configuration>


不要在同一页面上混合使用HTTP和HTTPS。如果您有一个通过HTTP提供的表单页面,那么我将对提交数据感到不安-如果不执行查看源并进行搜寻,就无法查看提交是通过HTTPS还是HTTP进行的。

通过HTTPS连同提交链接一起提供表单并没有太大的优势。


我已经通过许多解决方案来检查$ _SERVER [HTTPS]的状态,但似乎不可靠,因为有时它没有设置或设置为on,off等,导致脚本进行内部循环重定向。

如果您的服务器支持$ _SERVER [SCRIPT_URI],这是最可靠的解决方案

1
2
3
4
5
if (stripos(substr($_SERVER[SCRIPT_URI], 0, 5),"https") === false) {
    header("location:https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
    echo"<meta http-equiv='refresh' content='0; url=https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]'>";
    exit;
}

请注意,根据您的安装,您的服务器可能不支持$ _SERVER [SCRIPT_URI],但如果支持,则是更好的脚本。

您可以在此处检查:为什么某些PHP安装中有$ _SERVER ['SCRIPT_URI']而有些却没有


您不应该出于安全原因。特别是在这里使用cookie时。它使您对基于cookie的重播攻击敞开了大门。

无论哪种方式,都应该使用Apache控制规则进行调整。

然后,您可以测试是否启用了HTTPS,并在需要时根据需要重定向。

您应该仅使用FORM POST(无获取)重定向到付款页面,
并且在没有POST的情况下访问该页面应定向回其他页面。
(这会引起人们的热跳。)

http://joseph.randomnetworks.com/archives/2004/07/22/redirect-to-ssl-using-apaches-htaccess/

是一个很好的起点,很抱歉没有提供更多。但是您确实应该通过SSL推送所有内容。

它具有过度保护的功能,但至少您的担心更少。


也许这可以帮到您,这就是我为我的网站所做的工作,它就像一个魅力:

1
2
3
4
5
6
$protocol = $_SERVER["HTTP_CF_VISITOR"];

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

我已经使用了此脚本,并且该脚本在整个网站上都能正常工作。

1
2
3
4
5
6
if(empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] =="off"){
    $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    enter code hereheader('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $redirect);
    exit();
}


1
2
3
4
5
6
7
8
<?php
// Require https
if ($_SERVER['HTTPS'] !="on") {
    $url ="https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
    header("Location: $url");
    exit;
}
?>

这么简单


推荐阅读