3

作为我正在制作的登录系统的一部分,我在以每个客户端命名的唯一会话中跟踪失败的登录尝试:

if($login_failed) {

            // update failed login attempts
            $session_name = 'failed_attempts'.$_SERVER['REMOTE_ADDR'];

            if(!isset($_SESSION[$session_name])) {
                $_SESSION[$session_name] = 1;               
            }
            else {
                $_SESSION[$session_name] += 1;  
            }

}

如您所见,为了确定每个会话的唯一名称,我将用户的 IP 地址附加到字符串“failed_login_attempts”的末尾。

如果用户达到 5 次失败尝试,我需要在每次后续尝试时填写验证码。

我只是担心可能存在一些网络,其中许多用户被分配了相同的 IP 地址,在这种情况下,如果 1 个用户无法登录,他们都会开始看到验证码,即使只有 1 个用户需要显示验证码。

这是合理的还是从来没有两个用户可以拥有相同 IP 的情况,例如他们可能有相同的前 3 个八位字节但最后一个数字会不同,在这种情况下我不必担心。

如果多个用户有可能共享同一个 IP,那么确定会话名称的唯一标识符以将未登录用户链接到会话的好方法是什么?

4

3 回答 3

6

该会话已经是唯一的,因为它与该特定浏览器上该特定用户的 cookie 相关联。您无需担心它会泄露给其他用户。

会话 ID将所有这些联系在一起。

幕后实际发生的是,PHP 在浏览器上存储了一个带有唯一 ID(会话 ID)的 cookie,该 ID 与存储在服务器上的数据结构相关联。除了那个 id 之外,没有任何实际的会话数据离开服务器。它实际上是一个文件,如果你在你的 php 文件夹中四处寻找,你可以看到它。

于 2012-05-02T02:18:13.830 回答
1

在大多数学校、家庭和办公室网络中,您的用户共享 IP 地址,因为他们将从 NAT 内部或通过出站防火墙访问更广泛的 Internet。用于uniqid()生成与每个故障相关联的唯一值。但这并不是完全必要的,因为session_id()已经为每个用户会话拥有一个唯一的值。

要跟踪会话中的故障,您真正需要做的就是在该会话中增加一个变量。

if (failed_login) {
  $_SESSION['failed_logins']++;
}

$threshold = 5;
if ($_SESSION['failed_logins'] >= $threshold) {
   // Do whatever is needed when too many failures occur
}

但是请注意,这不能阻止用户简单地重新启动浏览器以获取新会话。您可以添加更多的箍来跳过,例如还记录用户代理,但这也可能导致同一网络上的其他用户的潜在冲突,并且仍然可以被聪明的最终用户欺骗或更改以绕过您的限制。

于 2012-05-02T02:18:41.650 回答
0

更好的解决方案是在用户表中标记/增加一列,当它达到 5 时,触发验证码。成功登录后,将值重置为 0。

于 2015-09-01T14:32:06.263 回答