扫码登录 = 用手机作为可信设备,帮 PC 完成一次"无密码登录授权"
核心是三点:
- 一个临时二维码(带状态)
- 手机端确认身份
- PC 端被动等结果(长轮询 / WebSocket)
二、扫码登录里涉及哪些角色?
一共 4 个角色,别少想了:
[PC 浏览器]
[PC Web Server]
[Mobile App]
[统一认证服务 Auth Server]
真实大厂一定有 统一认证服务,不是各业务自己玩。
三、完整流程(一步一步,重点)
下面是最标准、最通用的一套流程(微信 / 钉钉 / 飞书 / GitHub 都是变种)。
Step 1:PC 请求"登录二维码"
PC → Web Server
GET /login/qrcode
Web Server → Auth Server
Auth 服务生成一个 临时登录凭证:
text
qrId = UUID
并初始化状态:
json
{
"qrId": "abc123",
"status": "WAIT_SCAN",
"expireTime": now + 2min
}
👉 注意:此时还没登录
PC 拿到二维码
二维码内容不是账号,而是:
https://auth.xxx.com/scan?qrId=abc123
Step 2:PC 开始"等结果"
PC 页面此时会:
- 开一个 WebSocket
- 或者 轮询接口
text
GET /login/qrcode/status?qrId=abc123
Step 3:手机扫码
手机扫码 → 打开 App
App 拿到:
qrId = abc123
手机 → Auth Server
POST /scan
{
qrId: "abc123",
userToken: "mobile_login_token"
}
Auth Server 做三件事:
- 校验 qrId 是否存在 / 未过期
- 校验手机用户已登录
- 绑定关系:
json
{
"qrId": "abc123",
"userId": 10086,
"status": "SCANNED"
}
👉 此时 PC 仍然未登录
Step 4:手机"确认登录"
App 弹窗:
"是否确认在 PC 登录?"
用户点 确认。
手机 → Auth Server
POST /confirm
{
qrId: "abc123"
}
Auth Server:
json
{
"qrId": "abc123",
"userId": 10086,
"status": "CONFIRMED"
}
并生成:
- 登录态(session / jwt)
- 或一次性登录 ticket
Step 5:PC 被动感知"登录成功"
PC 轮询 / WS 收到:
json
{
"status": "CONFIRMED",
"loginToken": "xxxxx"
}
PC → Web Server
POST /login/byToken
Web Server:
- 校验 token
- 写 cookie / session
👉 PC 登录完成
四、状态机是整个系统的核心(重点)
扫码登录 本质是一个状态机。
text
WAIT_SCAN
↓
SCANNED
↓
CONFIRMED
↓
EXPIRED
每一步都必须是 幂等 + 可校验
五、状态存在哪?Redis 是标配
为什么不用数据库?
- 生命周期极短(1~2 分钟)
- QPS 高
- 不要求持久化
Redis 结构示例
text
key: qr:login:abc123
value:
{
status: SCANNED,
userId: 10086
}
TTL: 120s
六、PC 端是"怎么等结果的"?
两种主流方式:
方案一:短轮询(简单但不优雅)
text
每 1s 调一次状态接口
优点:
- 实现简单
缺点:
- 浪费 QPS
方案二:WebSocket / SSE(主流)
PC 建立 WS
Auth Server 状态变更 → 主动推送
优点:
- 实时
- 低消耗
👉 微信网页版 / 钉钉网页版都是这样。
七、安全点(非常容易被追问)
1️⃣ 二维码必须短期有效
- 1~2 分钟
- Redis TTL
2️⃣ 二维码只能用一次
- CONFIRMED 后立即失效
- 防止重放
3️⃣ 手机端必须已登录
扫码 ≠ 登录
扫码只是"授权"。
4️⃣ 防止 CSRF / 劫持
- qrId 不包含任何用户信息
- token 必须服务端校验
八、为什么这个流程设计得"这么绕"?
你可以用一句话总结:
扫码登录的本质,是把"输入密码"这件事,转移到一个已登录的可信设备上完成
所以复杂点都在:
- 状态同步
- 安全校验
- 跨端通信
九、如果你在面试,我会怎么追问你(提前帮你挡)
面试官:
👉 "为什么不扫码直接登录?"
你答:
因为扫码只是识别设备,登录必须经过用户确认,否则存在被偷拍二维码劫持的风险。
面试官:
👉 "Redis 挂了怎么办?"
你答:
扫码登录是非核心链路,可直接失败,不影响账号安全。
面试官:
👉 "高并发下 Redis 会不会扛不住?"
你答:
key 短期存在、访问模式简单、可水平扩展,QPS 可控。
十、把它压缩成「架构一句话」
扫码登录通过 Redis 维护短期二维码状态,手机端完成身份确认,PC 端通过轮询或 WebSocket 被动感知结果,实现安全的跨端无密码登录。