单设备登录实现方案

673 阅读5分钟

单设备登录实现方案

要实现单设备登录,需设立一种机制,确保同一账号在不同设备上不能同时保持活跃。从前端角度来说,常见的实现方式主要有两种:

1. 基于 Token 版本控制(推荐)

1.1 核心思想

Token 版本号(token_version)充当唯一凭证,每次新设备登录时,版本号 +1,旧 Token 失效。此机制通过对 Token 版本的精确管理,使得服务器能够准确判断当前请求的合法性,有效保障单设备登录的安全性和稳定性。

1.2 流程拆解

用户首次登录

  • 用户登录后,数据库中的 token_version 设为 1。这一步骤为后续的版本控制奠定基础,明确了初始状态。
  • 后端生成 JWT Token,并在 负载(payload) 中加入 {userId: 1, tokenVersion: 1}。JWT Token 作为用户身份验证的关键凭证,包含了用户 ID 和当前的 Token 版本信息,确保身份验证的准确性和完整性。
  • 返回 Token 给前端,前端存储在 localStorage 或 请求头字段(Authorization )中。前端妥善存储 Token,以便后续请求中携带,实现用户身份的验证和识别。

用户在新设备登录

  • 新设备登录后,后端查询该用户的 token_version,然后 +1,更新到数据库(如 token_version = 2)。后端通过查询和更新操作,确保数据库中记录的 Token 版本始终是最新的,为后续的验证提供准确依据。
  • 生成新的 Token {userId: 1, tokenVersion: 2},返回给新设备。新的 Token 携带了更新后的版本信息,保证新设备登录的合法性和有效性。

旧设备携带 Token 访问接口

  • 旧设备的 Token 仍然是 {userId: 1, tokenVersion: 1},但数据库中 token_version = 2。由于版本不一致,旧设备的 Token 已无法通过验证。
  • 服务器验证 Token,发现 tokenVersion!== 数据库的 token_version,返回 401,拒绝访问。服务器通过严格的验证机制,确保只有合法的 Token 才能访问接口,保障系统的安全性。

旧设备强制下线

  • 旧设备前端收到 401 响应后:
    • 清除本地 Token,确保本地不再保存已失效的凭证。
    • 跳转到登录页,引导用户重新进行登录操作。
    • 提示 "账号已在其他设备登录,请重新登录",向用户清晰解释下线原因,提升用户体验。

该方案核心是维护了 token_version 的版本值,是实现单设备登录最简单的方案。通过简洁的版本控制逻辑,有效实现了单设备登录的功能,降低了开发和维护的难度。

2. 基于 WebSocket 的实时强制下线

2.1 核心思想

每次用户在新设备登录时,服务器通过 WebSocket 通知旧设备下线,旧设备收到消息后清除 Token 并强制登出。此方案利用 WebSocket 的实时双向通讯特性,实现了对旧设备的即时下线控制,极大提升了用户体验和系统安全性。

2.2 流程拆解

用户首次登录

  • 用户登录后,服务器建立 WebSocket 连接,并在 Redis 或者数据库中存储对应状态,如:{userId: 1, socketId: "xm123"} 以记录该设备的 WebSocket 连接 ID。服务器通过建立连接和存储状态,为后续的实时通讯和设备管理提供了基础。

用户在新设备登录

  • 新设备登录后,服务器检测到该用户已有活跃连接。服务器通过实时监测,能够及时发现同一用户在不同设备上的登录行为。
  • 给旧设备发送 WebSocket 消息:"你的账号已在其他设备登录,请重新登录"。通过发送明确的通知消息,告知旧设备用户账号的异常登录情况。
  • 删除旧设备的 WebSocket 连接记录,确保系统中只保留当前活跃设备的连接信息。
  • 新设备建立 WebSocket 连接,存储 {userId: 1, socketId: "xm456"}。新设备成功建立连接并存储相关信息,保证后续通讯的顺畅。

旧设备收到 WebSocket 消息

  • 旧设备监听到 "被踢下线" 消息:
    • 清除本地 Token,确保本地不再保存已失效的凭证。
    • 自动跳转到登录页,引导用户重新进行登录操作。
    • 提示 "账号已在其他设备登录",向用户清晰解释下线原因,提升用户体验。

与基于 Token 版本控制相比,此方案核心是利用了 WebSocket 双向通讯的能力来实现强制下线的功能,好处是可以做到即时响应,麻烦的地方是需要重新对接 ws 协议,增加了开发和维护的复杂性。

3. 两种方案差异对比

方案优势劣势
基于 Token 版本控制逻辑简单,后端维护 Token 版本即可,兼容性好需要前端主动处理 401,可能有短暂的延迟
基于 WebSocket 实时强制下线即时性强,用户体验更好需要 WebSocket 连接,维护连接状态,断连时需要额外处理

4. 方案结合使用

可以以 WebSocket 优先,当 WebSocket 连接异常时,后端回退到 Token 版本校验。这样既能保证即时强制下线,也能兼容不支持 WebSocket 的场景。在实际应用中,根据用户设备和网络环境的不同,灵活切换验证方式,确保系统的稳定性和用户体验。例如,在网络环境较好、设备支持 WebSocket 的情况下,优先使用 WebSocket 实现即时下线;而在网络不稳定或设备不支持 WebSocket 时,自动切换到 Token 版本校验,保障系统的正常运行。同时,还可以在系统中加入日志记录功能,对每次登录和下线操作进行详细记录,以便后续的问题排查和数据分析。