我想检测用户是否正在查看安全页面,如果没有,则重定向(用于登录)。
然而,在我看到服务器变量之前,我的站点通过了一个代理,而代理(现在)告诉我$_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中重定向逻辑的建议:
- 通常使用
window.location
而不是location
是可取的,可以在这里找到解释 - 对于协议的简单替代,Regex似乎有点过头了
- 重定向逻辑应该尽快执行,因为在重定向的情况下,每一个额外的文档处理都是不必要的
- 禁用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>';
}