关于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;
}
?>

这么简单


推荐阅读

    linux命令删除用户组?

    linux命令删除用户组?,管理,密码,系统,用户组,用户,概念,命令,文件,管理员,

    linux操作数据库命令?

    linux操作数据库命令?,地址,服务,系统,密码,数据库,工具,名字,首页,命令,参

    linux系命令的操作?

    linux系命令的操作?,工作,系统,信息,网络,命令,基础,简介,管理,目录,操作,lin

    linux执行多次命令?

    linux执行多次命令?,系统,信息,标准,工作,情况,命令,周期性,服务,代码,时间,l

    linux中用户创建命令?

    linux中用户创建命令?,密码,系统,用户,软件,命令,联系方式,管理,信息,用户

    linux并行化执行命令?

    linux并行化执行命令?,系统,工具,信息,命令,名称,网络,管理,首页,服务,暂停,L

    linux注销命令用户?

    linux注销命令用户?,系统,服务,密码,地址,工作,命令,状态,工具,信息,基础,lin

    linux打断执行的命令?

    linux打断执行的命令?,系统,状态,网站,标准,通用,客服,人员,名字,网络,暂停,L

    linux系统用户命令?

    linux系统用户命令?,系统,工作,地址,信息,管理,命令,目录,时间,电脑,名称,请

    linux操作常用命令?

    linux操作常用命令?,工作,系统,地址,信息,命令,目录,管理,标准,基础,工具,lin

    linux命令没执行完?

    linux命令没执行完?,系统,设备,工具,情况,密码,状态,电脑,管理,材料,服务,Lin

    linux操作命令重命名?

    linux操作命令重命名?,图片,软件,名称,名字,文件,命令,状态,代码,工具,系统,L

    shell中执行linux命令?

    shell中执行linux命令?,系统,名称,环境,管理,工作,代码,技术,软件,经理,基础

    linux命令所有用户?

    linux命令所有用户?,系统,密码,信息,情况,名称,命令,用户,时间,地址,位置,如

    linux命令进入用户?

    linux命令进入用户?,系统,密码,用户,地址,信息,软件,命令,用户名,联系方式,

    linux打印命令执行?

    linux打印命令执行?,信息,系统,工具,服务,命令,发行,基础,位置,设备,时间,怎

    linux命令用户管理?

    linux命令用户管理?,系统,密码,管理,工作,信息,地址,工具,命令,用户,基础,LIn

    linux用户与组的命令?

    linux用户与组的命令?,管理,系统,名称,用户组,密码,用户,命令,情况,信息,单

    linux命令执行安装?

    linux命令执行安装?,软件,系统,管理,网站,官网,市场,中心,最新,灵活,工作,如