PHP / Javascript:告诉同一网络中的两台计算机
Posted
技术标签:
【中文标题】PHP / Javascript:告诉同一网络中的两台计算机【英文标题】:PHP/Javascript: Tell two computers apart from same network 【发布时间】:2011-04-29 15:09:51 【问题描述】:我正在开发一个网站,不允许您在一台计算机上登录多个帐户,但我不知道该怎么做。方法必须是:
跨平台(可用于 Windows/Mac/Linux 客户端)。 独立于浏览器。这是为了避免某些用户利用多个用户获取不公平的优势,同时仍然允许本地网络上的两个人连接,只要他们在不同的计算机上。
有什么建议吗?
【问题讨论】:
【参考方案1】:您可以尝试使用持久性 Cookie,例如“Evercookie”http://samy.pl/evercookie/,这样您就可以使用独特的 cookie 来识别每台计算机,并且它将是持久性的。
那么您需要做的就是将该 cookie 链接到您的会话处理架构。
编辑: 正如 Claudiu 指出的那样,您还需要检查用户是否启用了 JS,并在它被禁用的情况下拒绝访问。
所有使用 IP 地址进行验证的方法都有 2 个问题: - 任何人都可以使用代理并绕过它们 - 它不适用于 NAT'ed 环境
【讨论】:
用户可以禁用javascript,因此可以绕过您的方法 Evercookie 看起来很有希望。无论如何,人们都需要启用 javascript 才能使用该网站,而且它仍然比使用 Java 更好,更多的用户已经禁用了它。 将删除我的答案,因为这完全一样。只有相关的附加信息:“由于 cookie 是针对每个浏览器而不是针对每台计算机的,因此您可能会限制每个 IP 使用一个特定的浏览器”并让我们知道您的进度! @sunn0 这将迫使人们在最坏的情况下使用不同的浏览器。如果我找到一种对我或用户都不麻烦的方法,我会通知您。 如果您结合建议的答案,如果他们不使用 X-Forwarded-For 标头,它将强制相同 IP 上的用户使用相同的浏览器。我认为这是最好的。【参考方案2】:会话 ID 应该很容易区分它们。
试试这个:
<?php
$a = session_id();
if(empty($a)) session_start();
echo "SID: ".SID."<br>session_id(): ".session_id()."<br>COOKIE: ".$_COOKIE["PHPSESSID"];
?>
显示您的 ID 的三种方法。 Session_id() 是最可靠的。我注意到 Firefox 没有得到 SID,Internet Explorer 没有得到PHPSESSID
。两者都报告 session_id。
【讨论】:
【参考方案3】:编辑:我认为我的答案是一个 hack,并希望看到一个最佳实践替代方案。
尽管我很讨厌他们,但在这里检查 Flash Cookies 也可以。大多数用户甚至都不知道他们在计算机上,因此您不必担心他们会被删除。转到此链接,看看有多少人在您不知情的情况下长时间坐在您的计算机上:Flash Cookie Manager。
虽然我认为 Flash 不适用于 iPhone,但你没有提到它。
这是 adobe 对 flash install base 的看法。 Wikipedia 也有闪存渗透能力。
【讨论】:
这似乎真的是我的问题的答案,将更彻底地调查它。如果相信来自 Adobe 的数字,几乎每个人都激活了 Flash。应该能够想出允许 iPhone 或类似设备连接的东西。我会看看我能用这些信息做什么。 未知 cookie 的数量相当可怕...该死。 (+1 向我展示了我的系统上存储了多少我从来不知道的东西)。【参考方案4】:唯一的方法是通过客户端的 IP 地址来区分,正如其他人在此处提到的那样,但是如果您的用户要使用代理,事情就会变得更加棘手。
代理之间有一个事实上的标准来添加一个名为“X-Forwarded-For”的 HTTP 标头,它反映了客户端的内部 IP。 $_SERVER['REMOTE_ADDR'] 加上 X-Forwarded-For 的值原则上为您提供了客户端机器的唯一标识。但是,使用真实 IP 地址的高级攻击者可以轻松伪造 X-Forwarded-For。
在php中获取X-Forwarded-For的值:
$headers = apache_request_headers();
$full_client_id = $_SERVER['REMOTE_ADDR'] . '|' . $headers["X-Forwarded-For"];
$full_client_id,可能看起来像例如'123.1.2.3|192.168.1.1' 将为您提供几乎可靠的标识,将其存储在您的会话数据中,并与每个新创建的会话进行比较。
这至少可以保护您免受非高级用户非常明显的滥用。
【讨论】:
有用,证明可以做到,但不幸的是,正如您所说,它可以被高级攻击者伪造。这使得这种方法毫无用处。【参考方案5】:我看到的唯一方法是通过 IP 检查,如果您已经连接了 $_SERVER['REMOTE_ADDR'],那么不要让其他任何一个。当然,在某些情况下,您可以在两台不同的 PC 上拥有相同的 IP,但这是最安全的方式,因此您的用户应该注意这一点。
【讨论】:
但这不会让两个室友同时连接到不同的帐户,我想提供给我的用户。 是的,但是你必须放弃没有人能够闯入你的系统的想法......就像在系统上作弊 我不相信如果你真的想我的系统不会被破坏,这足以阻止人们这样做。如果计算机使用相同的 cookie,无论同一台计算机上的浏览器如何,使用代理都无济于事,这似乎是我必须走的路线。【参考方案6】:您需要考虑几个因素。
确保每个 IP 地址只有 1 个会话将是最好的方法,唯一的缺点是如果用户没有注销,您可能会遇到问题。
我会做的是
将登录的用户存储在一个表中并跟踪那里的最后活动,如果您的网站是一个用户可能在一段时间内不会更改页面的网站,那么您应该设置一个 javascript 心跳女巫,只需从浏览器 ping 您的服务器,以便PHP 始终是最新的。
如果用户 A 已登录,并且来自不同 IP 的另一次尝试尝试登录,那么您应该停用用户 A 的登录状态并允许用户 B 开始新会话。
您还应该跟踪用户用于登录的 IP 地址,这样您就可以拥有一个递增的表格,例如
user_id ip hits
--------------------------------------
1 xxx.yyy.zzz.244 6
1 xxx.yyy.zzz.224 4
1 xxx.yyy.zzz.264 1
1 xxx.yyy.zzz.124 1
1 xxx.yyy.zzz.174 1
2 aaa.bbb.zzz.678 3
.....
这样,如果用户 A 登录并且用户 B 尝试,您可以运行检查以查看此 IP 之前是否已使用过,如果已使用则直接注销,否则您可以问一个秘密问题在注册时提供以帮助解决安全方面的问题
【讨论】:
这仍然不允许来自同一 IP 的两个连接,只要它们位于两台不同的计算机上。 你不能从同一个 ip 同时连接不同的控制台。 问题不在于每个 IP 只允许一个会话(不会被强制)或不能同时从不同位置登录(这是不可能的)。问题是每台计算机只允许一个会话。同一网络下的多台计算机应该能够登录,但每台计算机只能有一个活动会话。【参考方案7】:您可以在数据库中放置一个位列 (IsLoggedIn) 来指示一个人当前是否已登录?
不起作用的事情以及原因:
IP:在路由器后面的本地 LAN 中的每个人都会在您的网站上显示为具有相同的 IP 地址。
Cookie:它们依赖于浏览器。例如,一个 cookie IE 在 Firefox 中不会被识别。
【讨论】:
如果用户使用多个帐户,则检查用户是否登录将无济于事。我知道那些行不通,所以,我想知道什么,还有什么行不通?以上是关于PHP / Javascript:告诉同一网络中的两台计算机的主要内容,如果未能解决你的问题,请参考以下文章
如何在同一个按钮上运行 php 操作和 javascript 代码