java - 限制同时登录的用户设备数

标签 java php security

问题。

网站(例如 Netflix)如何实现“只允许 2 台设备同时登录”等功能?

我的理解。

数据库中的用户表会有一个“logon_count”列。 session 表记录了 session ID、用户名、上次操作等。

将根据用户在访问 URL 时可以提供的内容执行多层检查以匹配 session cookie 或登录计数或清除空闲 session 。

但是。

假设用户想要绕过验证机制。正常登录,以某种方式记录有效的 cookie 并将其分发/复制到多个设备上。为所有人提供免费 Netflix。

当源 ip 不可靠并且可以伪造 HTTP header 时,服务器端代码如何判断每个 session 是否来自唯一设备,从而强制执行并发登录限制?

干杯, 拉尔夫

最佳答案

不管 Netflix 如何实现这个解决方案,让我们更抽象地考虑这种问题的一般解决方案。

首先,您需要能够将所谓的 session (主要用于保留用户应用程序状态)与在用户玩游戏时对用户进行身份验证的机制区分开来视频。当然,如果服务器只是将客户端提供的 session cookie 直接关联到设备,那么整个解决方案就会分崩离析,因为正如您推断的那样,我们可以轻松地将 cookie 复制到另一个客户端。

以更一般的方式解决这个问题有两个要求。

  1. 播放视频时,服务器必须有办法验证客户端
  2. 身份验证机制不得被任何其他客户端重复使用

登录 Netflix 本身没有实际意义,因为那是一个应用程序状态。这是一个完全不同的问题。您已经清楚地知道如何解决该问题。用户实际请求播放视频时的身份验证是您要问的另一个问题。

这需要一些不能被多个客户端重复使用的东西,因此它可以实现为 nonce .这是一个只能使用一次的加密 token 。

假设用户分块下载视频(30 秒缓冲区)。每次请求服务器下载一个视频 block 时,服务器都需要来自客户端的 token (这是不能重复使用的随机数),并在服务器端验证它。如果它 checkout ,它会将视频 block 连同一个新 token 发送回客户端。这可以在整个视频持续时间内继续发生。这样一来,如果另一个客户端要复制此 token 并尝试将其发送到服务器,服务器将不会接受任何具有相同 token 的 future 请求,理论上这可以防止多个设备访问多个视频(来自同一帐户) 同时。

一个实用但做作的例子

为了演示,让我们假设用户像这样登录到您的应用程序。

session_start();
if ($user->authenticate($username, $passwrod)) {
    $_SESSION['user_id'] = $user->id;
}

这为您的应用程序提供了一种在 HTTP 请求之间保留客户端状态的方法,这很好。然而,当用户要求播放视频时,必须发生其他事情来生成随机数。

$nonce = base64_encode(random_bytes(128));
$_SESSION["nonce"][$nonce] = false;
echo json_encode(["buffer" => $videoBufferData, "token" => $nonce]);

让我们想象一下,此代码发送一些 API 响应,为用户提供 30 秒视频缓冲区作为有效负载和 JSON 响应中的 token 。当用户请求下一个 30 秒缓冲区时,它必须与存储在 session 中的 token 匹配。

if (empty($_SESSION["nonce"][$_POST["token"]])) {
    $_SESSION["nonce"][$_POST["token"]] = true; // invalidate the current nonce
    // generate a new nonce
    $nonce = base64_encode(random_bytes(128));
    $_SESSION["nonce"][$nonce] = false;
}

现在,每次我们接受一个尚未使用的随机数时,我们也会为下一个播放负载生成一个新的随机数。即使用户将 session cookie 复制到另一个客户端,他们也永远无法以这种方式同时播放视频。因为一旦一台设备使用 token ,具有相同 session 的另一台设备仍然无法在下一个请求中重复使用相同的 token 并且它将无法接收 继续播放视频的 token 。所以他们会互相阻碍。

关于java - 限制同时登录的用户设备数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39651486/

相关文章:

java - Spring 电子邮件 Mime Base64 图像

java - 顺序搜索算法

java - 这个静态方法有什么作用?

php - Google Analytics/Google Ads 添加转化

security - 有没有办法对文档进行数字签名以证明它们在某个时间点存在

security - OAuth 和网络钓鱼漏洞,它们是否紧密地联系在一起?

Java双向加密库

java - 使用 apache POI 在现有 Excel 文件之间插入新列

php - 为什么 ( $_SESSION = [];) 使服务器无法处理请求?

php - 在现有电子邮件正文的底部添加一个 HTML 元素