142

我只有一个页面,我想强制作为 HTTPS 页面(Apache 上的 PHP)访问。如何在不使整个目录需要 HTTPS 的情况下做到这一点?或者,如果您将表单从 HTTP 页面提交到 HTTPS 页面,它是通过 HTTPS 而不是 HTTP 发送的吗?

这是我的例子:

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

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

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

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

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

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

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

4

22 回答 22

181

我之前做的方式基本上和你写的一样,但是没有任何硬编码的值:

if($_SERVER["HTTPS"] != "on")
{
    header("位置:https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    出口();
}
于 2008-09-17T17:56:15.730 回答
47

您可以在 Apache 上使用指令和 mod_rewrite 来做到这一点:

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

如果需要,您可以使用正则表达式使位置变得更智能。

于 2008-09-17T17:53:37.530 回答
43

您应该强制客户端始终使用HTTP 严格传输安全(HSTS) 标头请求 HTTPS :

// 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,上述逻辑会手动重定向用户,而不考虑是否支持,然后设置 HSTS 标头,以便进一步的客户端请求应该由浏览器重定向(如果可能)。

于 2012-08-27T15:53:12.610 回答
19

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

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

简单的 !

于 2015-06-23T10:37:31.957 回答
10

PHP方式:

$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 方式:

RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
于 2018-10-26T22:50:03.253 回答
9
// 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);
}
于 2010-12-23T15:47:01.897 回答
8

在负载均衡器后面运行时必须做这样的事情。帽子提示https://stackoverflow.com/a/16076965/766172

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;
    }
}
于 2014-12-18T21:56:42.747 回答
5

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

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

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

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

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

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

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

于 2012-12-28T15:46:31.103 回答
5

好的.. 现在有很多关于此的内容,但没有人真正完成“安全”问题。对我来说,使用不安全的东西是荒谬的。

除非你把它当作诱饵。

$_SERVER 传播可以根据知道如何更改的人的意愿进行更改。

同样正如 Sazzad Tushar Khan 和 thebigjc 所说,您也可以使用 httaccess 来执行此操作,这里有很多包含它的答案。

只需添加:

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

到您的 .httaccess 中的内容结束,仅此而已。

使用这两种工具,我们仍然没有尽可能安全。

剩下的很简单。如果缺少属性,即...

if(empty($_SERVER["HTTPS"])){ // SOMETHING IS FISHY
}

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


还说您已更新您的 httaccess 文件并检查:

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

您可以检查更多变量,即..

HOST_URI (如果有关于它的静态属性要检查)

HTTP_USER_AGENT (相同的会话不同的值)

所以我要说的是,当答案在于组合时,不要只满足于其中一个。

有关更多 httaccess 重写信息,请参阅 docs-> http://httpd.apache.org/docs/2.0/misc/rewriteguide.html

Some Stacks here -> Force SSL/https using .htaccess and mod_rewrite
and
Getting the full URL of the当前页面(PHP)
举几个例子。

于 2015-06-04T22:19:51.053 回答
3

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

请记住,显示表单的页面不需要通过 HTTPS 提供,它是最需要它的回发 URL。

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

于 2008-09-17T17:54:29.710 回答
3

如果您想使用 PHP 来执行此操作,那么这种方式对我来说非常有效:


<?php

if(!isset($_SERVER["HTTPS"]) || $_SERVER["HTTPS"] != "on") {
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"], true, 301);
    //Prevent the rest of the script from executing.
    exit;
}
?>

它检查 $_SERVER 超全局数组中的 HTTPS 变量,看它是否等于“on”。如果变量不等于on。

于 2020-07-01T15:25:09.387 回答
1

不要在同一页面上混合使用 HTTP 和 HTTPS。如果您有一个通过 HTTP 提供的表单页面,我会对提交数据感到紧张——如果不查看源代码并寻找它,我看不到提交是通过 HTTPS 还是 HTTP。

通过 HTTPS 提供表单以及提交链接并没有太大的优势。

于 2008-09-17T17:57:36.850 回答
1

对于那些使用 IIS 的人来说,在 web.config 中添加这一行会有所帮助:

<httpProtocol>
    <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
    </customHeaders>
</httpProtocol>
<rewrite>
    <rules>
        <rule name="HTTP to HTTPS redirect" stopProcessing="true">
              <match url="(.*)" />
              <conditions>
                 <add input="{HTTPS}" pattern="off" ignoreCase="true" />
              </conditions>
              <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
         </rule>
    </rules>
</rewrite>

完整的示例文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000"/>
             </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                      <match url="(.*)" />
                      <conditions>
                         <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                      </conditions>
                      <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
                 </rule>
            </rules>
       </rewrite>
   </system.webServer>
</configuration>
于 2017-04-06T09:27:02.347 回答
1

使用它是不够的:

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

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

于 2016-08-17T12:47:12.793 回答
1
if(location.protocol!=='https:'){location.replace(`https:${location.href.substring(location.protocol.length)}`);}
于 2021-06-27T11:07:17.810 回答
1

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

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

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

我希望这有帮助。

于 2016-08-03T10:29:09.233 回答
1

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

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

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'] 而其他没有

于 2016-08-31T00:26:00.907 回答
0

出于安全原因,您不应该这样做。特别是如果饼干在这里发挥作用。它让您对基于 cookie 的重放攻击敞开大门。

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

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

您应该只使用 FORM POST(不获取)重定向到付费页面,并且在没有 POST 的情况下访问该页面应该被重定向回其他页面。(这会抓住人们只是热跳。)

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

是一个很好的起点,很抱歉没有提供更多。但是你真的应该通过 SSL 推动一切。

这是过度保护,但至少你有更少的担忧。

于 2008-09-17T17:58:15.600 回答
0

作为替代方案,您可以使用X-Forwarded-Proto标头强制重定向到 HTTPS。

在 .htaccess 文件中添加这些行

### Force HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
于 2021-01-04T15:07:22.350 回答
0

也许这个可以帮助你,这就是我为我的网站所做的,它就像一个魅力:

$protocol = $_SERVER["HTTP_CF_VISITOR"];

if (!strstr($protocol, 'https')){
    header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
    exit();
}
于 2018-04-17T09:48:12.607 回答
-1

我已经使用了这个脚本,它在网站上运行良好。

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();
}
于 2016-07-26T00:11:31.283 回答
-2
<?php 
// Require https
if ($_SERVER['HTTPS'] != "on") {
    $url = "https://". $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
    header("Location: $url");
    exit;
}
?>

就这么简单。

于 2014-09-29T00:23:02.167 回答