浏览器能否限制单设备同时仅运行一个网站实例?
结论
浏览器环境不存在绝对无法绕过的设备唯一标记方案,但通过多层技术组合,可以覆盖绝大多数普通用户的多开作弊场景,实现单设备运行实例数限制,对于网页游戏的反作弊需求来说投入产出比足够高。
具体实现方案
按拦截优先级从易到难分为三层:
- 第一层:同域跨标签页实时计数(拦截普通用户多开)
现代浏览器同域下的标签页可以直接通过BroadcastChannel接口实现跨页通信,不需要申请任何权限,兼容性覆盖Chrome、Firefox、Edge等所有主流现代浏览器。
实现逻辑很简单:每个游戏实例启动时先生成唯一的临时实例ID,通过广播通道发送上线消息,所有已运行的同站实例收到消息后回传自身的存活状态;新实例统计当前收到的存活实例总数,如果超过预设阈值(比如单设备仅允许1个实例运行),直接终止加载并弹出多开提示。
基础代码示例:
这层可以100%拦住不知道改前端代码、直接开多标签的普通用户。// 实例同步通道 const syncChannel = new BroadcastChannel('game_instance_counter') const currentInstanceId = crypto.randomUUID() let aliveInstanceCount = 1 // 启动时广播上线查询 syncChannel.postMessage({ type: 'query_alive', instanceId: currentInstanceId }) // 监听其他实例的消息 syncChannel.onmessage = (e) => { if (e.data.type === 'query_alive') { // 收到其他新实例的查询,回传自己存活的消息 syncChannel.postMessage({ type: 'alive_reply', targetId: e.data.instanceId }) } if (e.data.type === 'alive_reply' && e.data.targetId === currentInstanceId) { aliveInstanceCount++ // 超过阈值直接拦截 if (aliveInstanceCount > 1) { alert('当前设备仅允许运行一个游戏实例') window.close() } } } - 第二层:设备指纹校验(防清缓存、关通道重开)
组合多个浏览器、设备的固有特征生成哈希值作为设备唯一标记,上报给服务端做跨会话校验。可选取的低敏感度、兼容性好的特征包括:UserAgent信息、屏幕分辨率与色深、系统时区、默认语言设置、Canvas/WebGL渲染结果特征、系统已安装字体列表、CPU核心数、设备内存大小、浏览器支持的API列表。将所有特征拼接后做SHA256哈希生成设备ID,存在本地持久化存储,同时和用户登录态绑定上报。
注意:不要尝试调用高风险隐私接口获取硬件MAC、设备真实序列号这类信息,这类接口在现代浏览器中已经全部被禁用,还会触发隐私合规问题。 - 第三层:服务端长连接兜底(防前端篡改绕过)
游戏客户端和服务端建立WebSocket长连接时,服务端同时记录用户账号、对应设备ID的活跃连接数,一旦同账号+同设备ID下的活跃连接数超过阈值,直接拒绝新连接接入,或者踢掉最早建立的冗余连接。就算用户篡改前端代码绕开了前两层的客户端检测,这层服务端校验也能兜住绝大多数绕过行为。
方案局限性
所有浏览器端的反多开方案都没有绝对的不可绕过性,具备足够技术能力的用户可以通过指纹伪造、浏览器多开分身、虚拟机等方式绕过检测,但上述三层组合方案可以拦住95%以上的普通多开作弊行为,完全可以满足网页游戏的常规反作弊需求。
内容的提问来源于stack exchange,提问作者juicecup
相关产品推荐
相关产品推荐

