6

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

但是,在我看到服务器变量之前,我的网站会通过代理,并且代理(现在)告诉我,这$_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 实现或链接。

非常感谢!

4

3 回答 3

3

虽然已经在问题的评论中部分讨论过,但我将总结一些关于 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>
    ...
于 2013-02-07T22:14:06.430 回答
1

还有一种方法可以在没有客户端 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>';
}
于 2013-02-08T23:49:11.263 回答
1

只需使用客户端方法。如果您的代理不可配置,则该选项不可用。通过js检测和重定向很好。

于 2013-02-07T20:42:12.010 回答