【发布时间】:2011-04-29 15:09:51
【问题描述】:
我正在开发一个网站,不允许您在一台计算机上登录多个帐户,但我不知道该怎么做。方法必须是:
- 跨平台(可用于 Windows/Mac/Linux 客户端)。
- 独立于浏览器。
这是为了避免某些用户利用多个用户获取不公平的优势,同时仍然允许本地网络上的两个人连接,只要他们在不同的计算机上。
有什么建议吗?
【问题讨论】:
标签: php javascript networking local
我正在开发一个网站,不允许您在一台计算机上登录多个帐户,但我不知道该怎么做。方法必须是:
这是为了避免某些用户利用多个用户获取不公平的优势,同时仍然允许本地网络上的两个人连接,只要他们在不同的计算机上。
有什么建议吗?
【问题讨论】:
标签: php javascript networking local
您可以尝试使用持久性 Cookie,例如“Evercookie”http://samy.pl/evercookie/,这样您就可以使用独特的 cookie 来识别每台计算机,并且它将是持久性的。
那么您需要做的就是将该 cookie 链接到您的会话处理架构。
编辑: 正如 Claudiu 指出的那样,您还需要检查用户是否启用了 JS,并在它被禁用的情况下拒绝访问。
所有使用 IP 地址进行验证的方法都有 2 个问题: - 任何人都可以使用代理并绕过它们 - 它不适用于 NAT'ed 环境
【讨论】:
会话 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。
【讨论】:
编辑:我认为我的答案是一个 hack,并希望看到一个最佳实践替代方案。
尽管我很讨厌他们,但在这里检查 Flash Cookies 也可以。大多数用户甚至都不知道他们在计算机上,因此您不必担心他们会被删除。转到此链接,看看有多少人在您不知情的情况下长时间坐在您的计算机上:Flash Cookie Manager。
虽然我认为 Flash 不适用于 iPhone,但你没有提到它。
这是 adobe 对 flash install base 的看法。 Wikipedia 也有闪存渗透能力。
【讨论】:
唯一的方法是通过客户端的 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' 将为您提供几乎可靠的标识,将其存储在您的会话数据中,并与每个新创建的会话进行比较。
这至少可以保护您免受非高级用户非常明显的滥用。
【讨论】:
我看到的唯一方法是通过 IP 检查,如果您已经连接了 $_SERVER['REMOTE_ADDR'],那么不要让其他任何一个。当然,在某些情况下,您可以在两台不同的 PC 上拥有相同的 IP,但这是最安全的方式,因此您的用户应该注意这一点。
【讨论】:
您需要考虑几个因素。
确保每个 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 之前是否已使用过,如果已使用则直接注销,否则您可以问一个秘密问题在注册时提供以帮助解决安全方面的问题
【讨论】:
您可以在数据库中放置一个位列 (IsLoggedIn) 来指示一个人当前是否已登录?
不起作用的事情以及原因:
IP:在路由器后面的本地 LAN 中的每个人都会在您的网站上显示为具有相同的 IP 地址。
Cookie:它们依赖于浏览器。例如,一个 cookie IE 在 Firefox 中不会被识别。
【讨论】: