问题。
网站(例如 Netflix)如何实现“只允许 2 台设备同时登录”等功能?
我的理解。
数据库中的用户表会有一个“logon_count”列。 session 表记录了 session ID、用户名、上次操作等。
将根据用户在访问 URL 时可以提供的内容执行多层检查以匹配 session cookie 或登录计数或清除空闲 session 。
但是。
假设用户想要绕过验证机制。正常登录,以某种方式记录有效的 cookie 并将其分发/复制到多个设备上。为所有人提供免费 Netflix。
当源 ip 不可靠并且可以伪造 HTTP header 时,服务器端代码如何判断每个 session 是否来自唯一设备,从而强制执行并发登录限制?
干杯, 拉尔夫
最佳答案
不管 Netflix 如何实现这个解决方案,让我们更抽象地考虑这种问题的一般解决方案。
首先,您需要能够将所谓的 session (主要用于保留用户应用程序状态)与在用户玩游戏时对用户进行身份验证的机制区分开来视频。当然,如果服务器只是将客户端提供的 session cookie 直接关联到设备,那么整个解决方案就会分崩离析,因为正如您推断的那样,我们可以轻松地将 cookie 复制到另一个客户端。
以更一般的方式解决这个问题有两个要求。
- 播放视频时,服务器必须有办法验证客户端
- 身份验证机制不得被任何其他客户端重复使用
登录 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/