使用 PHP 从 HTTP 重定向到 HTTPS

Posted

技术标签:

【中文标题】使用 PHP 从 HTTP 重定向到 HTTPS【英文标题】:Redirecting from HTTP to HTTPS with PHP 【发布时间】:2011-07-03 15:23:24 【问题描述】:

我正在开发一个购物车网站,我想在用户输入帐单详细信息时将用户重定向到 HTTPS 页面,并在他注销之前保持下一页的 HTTPS 连接。

为了做到这一点,我需要在服务器上安装什么(我正在使用 Apache),以及如何从 php 完成重定向?

【问题讨论】:

【参考方案1】:

你可以随时使用

header('Location: https://www.domain.com/cart_save/');

重定向到保存 URL。

但我建议通过 .htaccess 和 Apache 重写规则来完成。

【讨论】:

我总是建议在重定向之前检查 $_SERVER['HTTPS']。 $_SERVER['HTTPS'] 并不总是设置,但最好先检查一下。这就是为什么我建议在 Apache 中使用一个有用的重写规则来做到这一点,它只在它不在 HTTPS 上时重定向。 虽然 Apache 建议不要使用额外的 .htaccess 文件(因为它会变慢),而是使用 Apache 的 *.conf 中的重写规则。【参考方案2】:

尝试这样的事情(应该适用于 Apache 和 IIS):

if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off") 
    $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit;

【讨论】:

它并不总是有效。我尝试使用它,但 $_SERVER 数组中没有“https”元素,因此它给出了“重定向过多”的错误。需要使用其他方法。 我必须测试 if( $_SERVER['HTTPS'] == "off") 才能使此代码正常工作。我认为这是因为我在 IIS 上,而不是像 OP 这样的 Apache。 注意:die() 或 exit() 放在标头重定向之后可能很重要,以防止页面的其余部分执行(并可能向客户端发送额外信息)(即黑客或浏览器)可能不尊重标题)。 根据您的服务器环境/设置,您可能需要使用 $_SERVER['HTTP_X_FORWARDED_PROTO'] 来检查 http/https 这是否容易受到注入攻击?如果$_SERVER['REQUEST_URI'] 包含特殊字符,比如换行符怎么办?【参考方案3】:

在 IIS 上使用 PHP 从 HTTP 重定向到 HTTPS

我无法重定向到 HTTPS 以在 Windows 服务器上工作 它运行 MS Internet Information Services (IIS) 版本 6。我更 以前在 Linux 主机上使用 Apache,所以我转向 Internet 帮助,这是我搜索时排名最高的 Stack Overflow 问题 对于 “php 将 http 重定向到 https”。但是,选择的答案不起作用 对我来说。

经过反复试验,我发现使用 IIS,$_SERVER['HTTPS'] 是 对于非 TLS 连接,设置为 off。我认为下面的代码应该 帮助通过搜索引擎提出此问题的任何其他 IIS 用户。

<?php
if (! isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] == 'off' ) 
    $redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header("Location: $redirect_url");
    exit();

?>

编辑:来自另一个Stack Overflow answer, 一个更简单的解决方案是检查if($_SERVER["HTTPS"] != "on")

【讨论】:

@JakeSylvestre 够公平的。鉴于此问题未标记为apache,我发布此答案是为了其他 IIS 用户(类似于我所处的情况),他们可能会通过搜索引擎访问此页面。我同意这样的观点,即答案是为了整个社区的利益,而不仅仅是 OP。【参考方案4】:

这是一个很好的方法:

<?php
if (!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || 
   $_SERVER['HTTPS'] == 1) ||  
   isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&   
   $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))

   $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
   header('HTTP/1.1 301 Moved Permanently');
   header('Location: ' . $redirect);
   exit();

?>

【讨论】:

运行良好,标记为良好的会返回重定向太多次,至少在 Chrome 中 条件!(isset($_SERVER['HTTPS']) &amp;&amp; ($_SERVER['HTTPS'] == 'on' 将始终为假,因为如果最后一部分为真,则第一部分为假。 @Max:我不明白你说什么。如果第二个条件为真($_SERVER['HTTPS'] == 'on'),那么第一个条件也必须为真(当然设置了服务器变量,因为它包含一个值!) 它对我有用,谢谢!【参考方案5】:

在我的 AWS beanstalk 服务器上,我没有看到 $_SERVER['HTTPS'] 变量。我确实看到 $_SERVER['HTTP_X_FORWARDED_PROTO'] 可以是“http”或“https”,因此如果您在 AWS 上托管,请使用:

if ($_SERVER['HTTP_HOST'] != 'localhost' and $_SERVER['HTTP_X_FORWARDED_PROTO'] != "https") 
    $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit;

【讨论】:

以上是关于使用 PHP 从 HTTP 重定向到 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

php - 标头位置重定向:https 到 https,http 到 http

PHP:将主域重定向到https:// www,子域重定向到https://(不带www)

没有 index.php 的 AWS ELB 将 HTTP 重定向到 HTTPS

如何停止从 HTTP 到 HTTPS 的重定向

Tomcat 不会从 HTTP 重定向到 HTTPS

将所有子域从 http 重定向到 https