【问题标题】:PHP - Redirect HTTPS to HTTP - infinite loopPHP - 将 HTTPS 重定向到 HTTP - 无限循环
【发布时间】:2011-12-05 18:35:49
【问题描述】:

我试图阻止通过 HTTPS 访问我网站上的某些页面,并且(无论出于何种原因)我想通过 PHP 而不是通过 .htaccess 来访问。

这是我正在使用的代码:

if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://mydomain.com");
}

但由于某种奇怪的原因,我陷入了无限循环,无法让它工作。当我在 firebug 中检查响应标头时,我看到 location 标头设置为 https://mydomain.com 而不是 http://mydomain.com,这导致了无限循环。

编辑:直接访问http://mydomain.com 确实有效。

另请注意:如果我将它们发送到不同的页面,这有效,但如果我将它们发送到同一页面,则无效。因此,如果我在mydomain.com/somePage.php 中运行上述代码,然后尝试通过https://mydomain.com/somePage.php 访问它,它将正确重定向到(非 SSL 版)主页。只有当我将它们重定向到具有不同协议的同一页面时,它才会忽略该协议。

我做错了什么?

【问题讨论】:

  • header("Location: http:// 而不是header("Location: https:// 的拼写错误……还是代码实际上是这样写的?
  • @Dennis:对不起,你是对的。误解。我会在您的代码中查找导致从 http-> https 重定向的其他地方。你在 httpd.conf/.htaccess 中有什么东西吗?或者甚至是其他地方的另一个 PHP 块?
  • 您需要isset 还是if (!empty($_SERVER['HTTPS'])) 就足够了?我不确定您是否需要在isset== 'on' 上加倍。如果它不是 https,则 $_SERVER['HTTPS'] 变量将为空,因此只需检查单个变量的值应该可以工作 - 至少这是我所假设的。我现在没有启用 HTTPS 的服务器进行测试。
  • 如果你删除301 标头会怎样?
  • 古怪。如果明天没有答案,我会在工作的服务器上测试它,看看会发生什么。

标签: php apache redirect https http-headers


【解决方案1】:

事实证明我的代码没有任何问题。服务器只是以一种弄乱我的标题的方式设置的。我正在使用engineHosting.com,我不得不说:他们非常有帮助。在与他们多次来回后,这是他们发给我的:

我们能够找到问题的根源,并可能让它(原文如此)解决问题,但修复本身会导致其他问题。让我解释一下。

我们的架构不是大多数网络主机的典型架构。您的帐户实际上由双防火墙、双入侵防御系统、双负载平衡器托管,还执行基于 SSL 硬件加速的角色、面向两个 apache Web 节点和一个庞大的 mysql 服务器后端。

问题在于我们如何在负载平衡器内进行 SSL 加速。我们有许多客户端想要检测用户何时访问仅用于 https 的页面,但绝不会想要检测用户何时在应该重定向到常规 http 的页面上.因此,我们在负载均衡器上启用了一个名为“仅限 http wan 优化压缩 SSL 站点”的选项,当请求的 url 已启用 https 时,它还将出站位置标头重写为 https。当您可能在动态提供的同一 URL 上有很多指向资产的链接但不小心将链接写为 http 时,这很有用。所以这实际上是一个特性,而不是一个错误(是的,我也不喜欢这个短语)。

为了解决您的特定用例,我们将您域的 SSL 配置文件更改为“普通/非 ssl 的 http 压缩”虚拟服务器设置。过去,您可能没有使用单服务器 Web 解决方案遇到此问题。在这种模式下操作的不幸后果是,在服务器级别执行 30 次重定向以将用户从 http 重定向到 https 的另一个用例可能会出现问题,具体取决于重定向的实现方式。为了安全起见,您应该验证您将在实际站点中使用的方法,如果遇到任何问题,请告诉我。

【讨论】:

  • 嘿,这个“功能”花了我一个上午的时间。感谢您发布此内容。
  • @Populus - 你也在 engineHosting 上吗?
【解决方案2】:

不完全确定,但我注意到以下几点:

  1. 如果您的 .htaccess 或服务器配置设置为坚持使用 HTTPS,您将无法在 php 级别解决此问题。

  2. 您在http://mydomain.com 上留下了尾部斜杠,这会创建一个隐含的重定向。尝试使用该位置中的完整实际路径——例如http://mydomain.com/index.htmlhttp://mydomain.com/index.php

【讨论】:

  • 从脚本发送标头后 .htaccess 会重定向吗?
  • 1) 不。就像我在问题中所说,直接访问http://mydomain.com 可以正常工作。 2)我在主页上运行它,我确实希望它们被重定向到那里。 3)implied redirect是什么意思?
  • 隐含重定向意味着没有名为“mydomain.com”的文件。服务器识别出这一点并为您添加斜线,然后使用配置中的规则搜索默认目录文件。这就是 Web 服务器的工作方式,这可能是几个重写步骤,如果它是服务器的默认设置,则可能有机会在其中添加 https: 的设置。最好是明确的,不要指望隐藏的东西会按照您的期望做,尤其是当它们不是时。
【解决方案3】:

我有一个运行 HTTPS 站点的自托管服务器。我做了一些快速测试,你的代码完全符合预期。这是我的代码(逐字逐句,仅更改了域):

redir.php

<?php
if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://mydomain.com/redir.php");
    exit;
}

if ( !isset($_SERVER['HTTPS']) || !$_SERVER['HTTPS'])
{
   echo "IT'S WORKING!";
}

?>

我肯定会说 - 正如 Jared Farrish 在他的聊天中所说 - 这是主持人的问题。他们的服务器配置中的某些内容强制重定向回 HTTPS。我不认为这是一个 PHP 错误。我的服务器运行 PHP 5.3.5 和 Apache 2.2.17。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-18
    • 2015-12-22
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2019-08-13
    相关资源
    最近更新 更多