当代理服务器*始终*声明安全连接时检测SSL


Detect SSL when proxy *always* claims a secure connection

我想检测用户是否正在查看安全页面,如果没有,则重定向(用于登录)。

然而,在我看到服务器变量之前,我的站点通过了一个代理,而代理(现在)告诉我$_SERVER['HTTPS']'on',而URI明确表示不是。当用户"安全"导航时,它还会显示'on'

通过http://https://导航都输出$_SERVER['SERVER_PORT']443

我没有能力对代理进行任何更改,所以我想知道:

  • PHP有没有其他选项可以让我检测真相或
  • 我是否坚持使用JavaScript的检测和重定向机制

我挖掘了这个问题的想法,但它们大多围绕着$_SERVER['HTTPS']变量的可信赖性。啊!

这个问题似乎至少遇到了类似的情况,但他/她能够通过调整apache解决方案来解决这个问题。

是否有其他PHP SERVER变量或技巧可用于检测用户的URI以什么开头?当我的网站被http和https浏览时,$_SERVER变量之间的唯一区别如下:

  • _FCGI_X_PIPE_(随机出现)
  • HTTP_COOKIE(sto-id-47873包含在非安全版本中,但我没有将其放在那里)
  • REMOTE_ADDR(这个和接下来的两个莫名其妙地不断变化!)
  • 远程主机
  • REMOTE_PORT("亲民",你为什么不断改变这个?)

这些物品中有没有足够结实,可以承受重量而不会碎裂并在以后引起疼痛?也许我不应该相信通过代理过滤的任何东西,因为它可能在任何给定的时间发生变化。

以下是我为此目的使用JavaScript的计划;这是我最好的吗?

function confirmSSL() {
    if(location.protocol != "https:") {
        var locale = location.href;
        locale = locale.replace(/http:'/'//,"https://");
        location.replace(locale);
    }
}
<body onLoad="confirmSSL()">...

我认为,如果用户在我的社区中禁用了JavaScript,那么他们希望知道自己在做什么。他们应该能够手动进入安全区域。什么样的<noscript>建议是常见的/良好的做法?也许是这样的?:

<noscript>使用导航https://blah.more.egg/fake以保护您的信息。</noscript>

有效的PHP解决方案(有很好的解释)将优先考虑正确的答案。请随时提交更好的JavaScript实现或链接。

非常感谢!

尽管在问题评论中已经进行了部分讨论,但我将总结一些关于JavaScript中重定向逻辑的建议:

  1. 通常使用window.location而不是location是可取的,可以在这里找到解释
  2. 对于协议的简单替代,Regex似乎有点过头了
  3. 重定向逻辑应该尽快执行,因为在重定向的情况下,每一个额外的文档处理都是不必要的
  4. 禁用JavaScript的浏览器至少应该显示一个通知,提示用户切换到https

我建议使用以下代码(从这里采用),它既短又高效:

<head>
    <script type="text/javascript">
        if (window.location.protocol != "https:") {
            window.location.href = "https:" + window.location.href.substring(window.location.protocol.length);
        }
    </script>
    ...
</head>
<body>
    ...
    <noscript>Please click <a href="https://my-cool-secure-site.com">here</a> to use a secure connection!</noscript>
    ...

只需使用客户端方法。如果您的代理是不可配置的,那么该选项将被禁用。通过js进行检测和重定向是可以的。

还有一种方法可以在没有客户端javascript的情况下实现重定向。如果客户端浏览器中禁用了JavaScript,则此方法可能特别有用
步骤是纯PHP,非常简单:

  • 启动会话
  • 如果是新会话,则重定向到https位置
  • 如果会话不是新的,可以假设用户已经被重定向

示例代码:

<?php
    session_start();
    if( !isset($_SESSION['runningOnHttps']) ) {
        $_SESSION['runningOnHttps'] = true;
        header('Location: https://my-cool-secure-site.com');
    }
?>

当然,您可以将此功能限制在禁用JavaScript的浏览器上,以创建一种"混合模式":每当与非JS浏览器进行新会话时,都可以向某种回调脚本发出请求,通知服务器发送位置标头:

some_landingpage.php发送一个包含隐藏iframe的初始<noscript>,它将加载redirect.php:

if( !isset($_SESSION['checkWasMade']) ) {
    $_SESSION['checkWasMade'] = true;
    echo '<noscript>
            <iframe src="redirect.php" style="visibility: hidden; position: absolute; left: -9000px;"></iframe>
          </noscript>';
}

redirect.php的请求会让您知道JavaScript已被禁用,并通过发送带有下一个实际请求的Location标头(见上文)来强制重定向。

当然,只有当协议在一个会话期间不会改变(神奇地?)时,这种方法才能可靠地工作。

更新:
上述所有处理非JavaScript用户代理的方法都可以通过更简洁的方法变得毫无意义:
我刚刚了解到,<noscript>也可以包含在<head>中,这允许通过<meta>标签进行重定向。

因此,some_landingpage.php可以在<noscript>:内发送初始元刷新

// The following echo must appear inside the html head
if( !isset($_SESSION['checkWasMade']) ) {
   $_SESSION['checkWasMade'] = true;
   echo '<noscript>
            <meta HTTP-EQUIV="REFRESH" content="0; url=https://my-cool-secure-site.com"> 
        </noscript>';
}