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

时间:2013-02-07 20:35:02

标签: php javascript https proxy

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

但是,在我看到服务器变量和代理(现在)告诉我$_SERVER['HTTPS']'on'时,我的网站会通过代理,而URI明确指出。当用户“安全地”导航时,它还会显示'on'

导航http://https://两者都输出$_SERVER['SERVER_PORT'] = 443

我无法对代理进行任何更改,所以我想知道:

  • PHP是否有其他选择让我发现真相或......
  • 我是否坚持使用JavaScript的检测和重定向机制。

我挖掘了this question的想法,但它们主要围绕着值得信赖的$_SERVER['HTTPS']变量。呸!

似乎this question至少经历过类似的事情,但是他/她能够通过调整apache解决方案来解决它。

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

  • _FCGI_X_PIPE_(随机出现)
  • HTTP_COOKIE(sto-id-47873包含在非安全版本中,但我没有将其放在那里)
  • REMOTE_ADDR(这个和接下来的两个一直在不断变化!)
  • REMOTE_HOST
  • 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实现或链接到一个。

非常感谢!

3 个答案:

答案 0 :(得分:3)

虽然在问题的评论中已经部分讨论过,但我将总结一些关于JavaScript中重定向逻辑的建议:

  1. 一般情况下,建议使用window.location代替location,可以找到here的解释。
  2. 对于简单替换协议,正则表达式似乎有点过分。
  3. 应该尽快执行重定向逻辑,因为在重定向的情况下,每个额外的文档处理都是不必要的。
  4. 禁用JavaScript的浏览器至少应显示一条通知,提示用户切换到https。
  5. 我建议使用以下代码(从here采用),这是简短而有效的:

    <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>
        ...
    

答案 1 :(得分:1)

只需使用客户端方法即可。如果您的代理是不可配置的,那么该选项就不存在了。通过js检测和重定向很好。

答案 2 :(得分:1)

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

  • 开始会话
  • 如果是新会话,请重定向到https位置
  • 如果会话不是新的,可以假设用户已被重定向

示例代码:

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

当然,您可以将此功能限制为禁用JavaScript的浏览器,以便创建一种混合模式&#39;:每当与非JS浏览器建立新会话时,请向某种回调脚本,通知服务器发送位置标题:

some_landingpage.php 发送包含隐藏iframe的初始<noscript>,该iframe将加载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>';
}