基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

PC 端扫码登录的完整交互流程和技术实现是怎样的?

知识点图片

PC 端扫码登录是目前非常普遍的登录方式(如微信、淘宝、Telegram 等)。它的核心原理在于:通过手机端已有的登录凭证(Session/Token),授权 PC 端获取登录凭证,从而完成登录。

这个过程本质上是一个将“临时 ID”与“用户身份”进行绑定的过程。

以下是完整的交互流程和技术实现详解。


一、 核心角色

  1. PC 端(Client A): 浏览器或桌面客户端,处于未登录状态,需要登录。
  2. 手机端(Client B): App,处于已登录状态,拥有用户的 Auth Token。
  3. 服务端(Server): 处理认证、生成二维码 ID、维护状态。

二、 完整交互流程 (Step-by-Step)

我们可以将流程分为四个阶段:生成二维码 -> 扫描二维码 -> 确认登录 -> 登录成功

阶段 1:生成二维码 (PC -> Server)

  1. 用户打开 PC 端登录页面,选择“扫码登录”。
  2. PC 端向服务端发起请求,获取二维码 ID(qr_iduuid)。
  3. 服务端生成一个唯一的、随机的 ID,将其存入缓存(如 Redis),并设置过期时间(例如 2 分钟)。初始状态为 WAITING(待扫描)。
  4. 服务端将这个 ID 返回给 PC 端。
  5. PC 端根据这个 ID 生成二维码图片(通常是一个包含 ID 的 URL,如 https://app.com/scan?id=xyz),展示给用户。
  6. 关键动作: PC 端开始监听这个 ID 的状态(通过轮询或 WebSocket)。

阶段 2:扫描二维码 (Mobile -> Server)

  1. 用户打开手机 App,扫描 PC 端的二维码,解析出 ID。
  2. 手机端将 ID 和自身的 Auth Token(用户身份凭证)发送给服务端。
  3. 服务端校验手机端的 Token 是否有效。
  4. 若有效,服务端将 Redis 中该 ID 的状态更新为 SCANNED(已扫描),并可能记录下扫码者的头像/昵称(用于在 PC 端展示,提升体验)。
  5. PC 端反馈: PC 端监听到状态变为 SCANNED,页面提示“扫描成功,请在手机上确认”。

阶段 3:确认登录 (Mobile -> Server)

  1. 手机端跳转到“确认登录”页面,显示“是否允许登录 PC 端?”。
  2. 用户点击“确认登录”按钮。
  3. 手机端向服务端发送请求:确认授权 ID xyz 登录。
  4. 服务端收到请求后:
    • 生成一个用于 PC 端登录的临时凭证(temp_tokencode)。
    • 将 Redis 中该 ID 的状态更新为 CONFIRMED(已确认)。
    • temp_token 预存或直接关联到该 ID 的数据中。

阶段 4:登录成功 (PC <-> Server)

  1. PC 端监听到状态变为 CONFIRMED,并同时获取到了服务端返回的 temp_token
  2. PC 端使用这个 temp_token 再次请求服务端,换取真正的长效登录凭证(如 Session IDJWT)。
  3. 服务端校验 temp_token 有效性,通过后返回用户信息和登录 Cookie/Token。
  4. PC 端保存凭证,跳转至主页,登录完成。

三、 技术实现细节

1. 二维码 ID 的状态机

服务端通常使用 Redis 存储 ID 的状态。一个 ID 的生命周期包含以下状态:

  • NOT_SCANNED (0): 初始状态,等待扫描。
  • SCANNED (1): 已扫描,等待用户点击确认。此时 PC 端通常会显示用户的头像。
  • CONFIRMED (2): 用户已确认。此时包含用于换取登录凭证的临时 Token。
  • EXPIRED (-1): 二维码超时失效。
  • CANCELED (-2): 用户在手机端点击了“取消”。

2. PC 端如何监听状态? (三种主流方案)

这是技术实现中最关键的部分,决定了用户体验的流畅度。

  • 方案 A:短轮询 (Short Polling)

    • 做法: PC 端每隔 1-2 秒发送一个 HTTP 请求询问 Server:“ID 状态变了吗?”
    • 优点: 实现简单,兼容性好。
    • 缺点: 延迟高,服务器压力大(大量无效请求)。
    • 适用: 早期方案,现在较少使用。
  • 方案 B:长轮询 (Long Polling) —— 推荐

    • 做法: PC 端发送请求,服务端将请求挂起(Hold)。直到状态发生变化(被扫描、被确认、超时),服务端才返回响应。PC 端收到响应后立刻发起下一次请求。
    • 优点: 实时性好,减少了无效请求次数。
    • 缺点: 占用服务端连接数。
    • 适用: 微信网页版、大多数扫码登录均采用此方案。通常设置 25-30 秒超时。
  • 方案 C:WebSocket

    • 做法: PC 端与服务端建立全双工 TCP 连接。状态变化时,服务端主动推送消息给 PC 端。
    • 优点: 性能最好,延迟最低,通信开销小。
    • 缺点: 开发维护成本稍高,需要处理断线重连。
    • 适用: 对实时性要求极高或已有 WebSocket 架构的应用(如 Telegram, Discord)。

3. 为什么需要“换取 Token”这一步?

在“阶段 4”中,为什么 PC 端拿到 CONFIRMED 状态后,不直接给它 Session,而是给一个 temp_token 让它再去换?

  • 安全性: 监听接口(轮询/Socket)通常是公开的或安全性较低的。如果在监听的响应包里直接返回用户的 Session ID,容易被中间人攻击或日志泄露。
  • 一次性验证: temp_token 是一次性的,用完即焚,极大降低了被劫持的风险。

四、 安全性设计 (Security Considerations)

扫码登录虽然方便,但也存在安全风险(如 QRLJacking 劫持攻击),必须注意以下几点:

  1. 二维码时效性 (TTL):
    二维码 ID 必须设置较短的过期时间(如 60-120 秒)。过期后 PC 端需重新请求生成新码,防止二维码被恶意截获后长时间利用。

  2. Token 绑定与一次性:
    用于 PC 登录的 temp_token 必须是一次性的,且有效期极短(如 30 秒)。

  3. 上下文信息展示 (防钓鱼):
    在手机端“确认登录”的页面,必须展示 PC 端的地理位置、设备类型、甚至 IP 地址。

    • 场景: 攻击者把自己的 PC 二维码发给受害者,骗受害者扫描。
    • 防御: 受害者手机上显示“正在尝试登录 广东深圳 的 Windows 设备”,如果受害者人在北京,就会警觉并取消。
  4. HTTPS:
    全链路必须使用 HTTPS 加密,防止 ID 和 Token 在传输层被窃听。


五、 总结:时序图描述

plaintext
PC端                  服务端(Redis)                  手机端
 |                        |                           |
 |--1. 请求二维码ID ----->|                           |
 |<--2. 返回ID (uuid) ----|                           |
 |                        |                           |
 |--3. 展示二维码(uuid)   |                           |
 |                        |                           |
 |--4. 长轮询(uuid) ----->| (Hold住请求...)           |
 |                        |                           |
 |                        |<--5. 扫码(uuid + Token)---|
 |                        | 验证Token, 状态=SCANNED    |
 |<--6. 返回(已扫描) -----|                           |
 |                        |                           |
 |--7. 再次长轮询(uuid) ->| (Hold住请求...)           |
 |                        |                           |
 |                        |<--8. 确认登录 ------------|
 |                        | 状态=CONFIRMED, 生成code   |
 |<--9. 返回(code) -------|                           |
 |                        |                           |
 |--10. 用code换Session ->|                           |
 |<--11. 返回登录Cookie --|                           |
 |                        |                           |
 |== 登录成功 ============|                           |

这就是 PC 端扫码登录完整的技术实现逻辑。它巧妙地利用了手机端已有的信任关系,通过一个共享的临时 ID,安全地将信任传递给了 PC 端。

00:00
00:00