问题。
网站(例如Netflix)如何实现“只允许2台设备同时登录”等功能?
我的理解。
数据库中的用户表将具有“logon_count”列。会话表记录会话ID,用户名,最后一次操作等。
将根据用户在访问URL时提供的内容,执行多层检查以匹配会话cookie或登录计数或清除空闲会话。
但是
假设用户想要击败验证机制。正常登录,以某种方式记录有效的cookie并在多个设备上分发/复制它。为所有人免费提供Netflix。
当源IP不可靠且HTTP头可以伪造时,服务器端代码如何判断每个会话是来自一个唯一的设备,从而强制执行并发登录限制?
干杯, 拉尔夫
答案 0 :(得分:1)
Netflix不依赖于logon_count
,而是取决于requesting_video_count
(或类似的东西)。因此,即使共享帐户cookie,也无关紧要。您可以根据需要从任意数量的设备登录,您可以同时从最多两个设备查看视频。
答案 1 :(得分:0)
无论Netflix如何实施此解决方案,让我们更抽象地考虑这个问题的一般解决方案。
首先,您需要能够区分您所谓的会话(主要用于保留用户应用程序状态),以及在用户播放时对用户进行身份验证的机制视频。当然,如果服务器只是将客户端提供的会话cookie直接关联到设备,那么整个解决方案就会崩溃,因为您推断我们可以轻松地将cookie复制到另一个客户端。
以更一般的方式解决此问题有两个要求。
登录Netflix本身没有实际意义,因为这是一个应用程序状态。这是一个完全不同的问题需要解决。你已经清楚地知道如何解决这个问题了。用户在实际请求播放视频时进行身份验证是您要问的另一个问题。
这需要多个客户端无法重用的东西,因此它可以实现为nonce。这是一个加密令牌,只能使用一次。
想象一下,用户以块(30秒缓冲区)下载视频。每次请求服务器下载一个视频块时,服务器都需要来自客户端的令牌(这是不能重复使用的nonce),并在服务器端进行验证。如果它签出,它会将客户端发送回视频块以及新令牌。这可以在整个视频期间继续发生。这样,如果另一个客户端要复制此令牌并尝试将其发送到服务器,则服务器将不会接受具有相同令牌的任何未来请求,理论上这会阻止多个设备访问多个视频(来自同一帐户< / em>)同时。
为了演示,让我们假设用户就像这样登录你的应用程序。
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响应中的令牌。当用户请求下一个30秒缓冲区时,它必须与会话中存储的令牌匹配。
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;
}
现在,每当我们接受尚未使用的随机数时,我们还会为下一个播放加载生成新的随机数。即使用户将会话cookie复制到另一个客户端,他们也永远无法以这种方式同时播放视频。因为一旦一个设备使用令牌,具有相同会话的另一个设备仍然无法在下一个请求和上重复使用相同的令牌,它将无法接收 new 继续播放视频的令牌。所以他们会互相阻碍。