首页 / 知识库 / python服务端进阶 / 解析用户登录场景案例

09 - 进阶场景:双令牌 / 多端登录 / 踢下线 / SSO

前面把登录的核心机制和安全都讲透了。这一章带你看几个真实产品里绕不开的进阶需求,理解它们在架构上是怎么落地的。

依然重思维:目标是让你”听得懂、说得清、会判断”,而不是给你一套可复制的代码。

一、Access / Refresh 双令牌:既要安全又要不频繁登录

矛盾在哪

第 07 章埋了个矛盾:

token 寿命设很长(如 7 天):用户不用老登录,体验好,但一旦被偷,攻击者能用很久 → 不安全
token 寿命设很短(如 15 分钟):安全,但用户每 15 分钟就要重新输密码 → 体验崩了

既要安全(短命),又要体验好(不用老登录),怎么办?——发两张令牌,各司其职

双令牌怎么分工

┌────────────────────────────────────────────────────┐
│ Access Token(干活的)                                │
│   寿命短:15 分钟                                      │
│   用途:每次访问接口都带它                             │
│   特点:无状态,验签就行,就算被偷也只能用 15 分钟      │
├────────────────────────────────────────────────────┤
│ Refresh Token(续命的)                               │
│   寿命长:7 天                                         │
│   用途:只在 Access 过期时,用它去换一张新的 Access     │
│   特点:服务端存一份(Redis),能被作废 → 退出/踢人用它  │
└────────────────────────────────────────────────────┘

工作流程:

登录:服务端一次发两张:Access(15分钟) + Refresh(7天)

平时访问:带 Access → 正常干活

Access 过期了:
   App 自动拿 Refresh 去 /refresh 接口换一张新 Access(用户完全无感)

Refresh 也过期了(7 天没动过):
   才需要重新输密码登录

退出登录:服务端把这个 Refresh 作废(从 Redis 删掉)
   → 无法再续命 → 手里的 Access 最多再撑 15 分钟就死

这套设计的精妙之处:把”无状态、高频”的活儿交给短命的 Access(不查库、性能好),把”要能控制、低频”的活儿交给 Refresh(存 Redis、能作废)。每次接口请求不查库,只有十几分钟一次的刷新才查库。 既拿到了 JWT 的性能,又拿回了退出登录的控制力——这是第 05 章”混用”思想最优雅的落地。

二、多端登录 与 踢下线

真实产品对”同一账号能在几个设备登录”往往有明确要求。三种典型策略:

策略 A:允许多端同时在线(微信那种:手机、电脑、iPad 都能同时登)
策略 B:同一账号只能一端在线(很多银行 App:新设备登录 → 旧设备被挤下线)
策略 C:限制数量(如"最多同时 3 台")

怎么实现?关键是服务端要有一张”在线登录表”

纯无状态 JWT 做不到这些(服务端根本不知道谁在线)。必须在 Redis 里维护每个用户的登录记录:

Redis 里为每个用户存一个登录列表:
   user:42:logins → [ 设备A的令牌id, 设备B的令牌id, ... ]

新设备登录时:
   策略 B(单端):清空列表,只留新设备 → 旧设备的令牌一验就发现"不在列表里" → 被踢
   策略 C(限 3 台):列表超过 3 个,就把最早的那个踢掉

“踢下线”的本质,其实就是第 07 章讲的”作废 token”:把某个设备的令牌从这张在线表里剔除(或拉进黑名单),它下次来验证时就被拒绝。所以你会发现:

多端登录、踢下线、退出登录、封号——本质是同一件事:服务端要能掌控”哪些令牌现在还算数”。 而这必然要求服务端存一份状态。

三、单点登录(SSO):一次登录,多个系统通用

要解决的问题

一家公司有很多系统:邮箱、OA、报销、Wiki……如果每个都要单独登录,员工要记一堆账号、登一堆次,很痛苦。

单点登录(SSO, Single Sign-On) 的目标:

登录一次,所有系统都认你。 退出一次,所有系统都退出。

核心思路(一句话认知)

把”登录/认证”这件事,从各个业务系统里**抽出来,交给一个专门的”认证中心”**统一负责:

              ┌──────────────────┐
              │    认证中心 SSO    │  ← 只有它管登录、发凭证
              └────────┬─────────┘
                       │ 你在这登录一次,拿到一个"通行凭证"
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
     邮箱系统         OA 系统        报销系统
   (不自己登录,   (不自己登录,   (不自己登录,
     拿凭证去问       拿凭证去问       拿凭证去问
     认证中心:       认证中心:       认证中心:
     "这人是谁?")   "这人是谁?")   "这人是谁?")

流程感受一下:

你访问 OA 系统 → OA 发现你没登录 → 把你重定向到认证中心
   → 你在认证中心登录(就这一次)→ 认证中心发给你一个凭证
   → 带着凭证回到 OA → OA 拿凭证向认证中心确认 → 认你,放行

接着你访问报销系统 → 报销发现你没登录 → 重定向到认证中心
   → 认证中心一看:"你刚登录过啊" → 不用再输密码,直接发凭证
   → 回到报销系统 → 放行 ✅(你感觉"根本没登录就进去了")
  • 你在业务里熟悉的 OAuth2 / OpenID Connect,就是实现这套”认证中心 + 各系统信任它”的标准协议。
  • “用微信/Google 账号登录别的网站”,本质也是 SSO 的思想——微信/Google 就是那个被大家信任的认证中心。

SSO 是个大话题,这里你只要建立这个认知:把认证从各系统抽出来集中管理,各系统信任统一的认证中心。 细节(协议流程、令牌交换)真要落地时再深入。

小结

  • 双令牌:短命 Access(无状态、高频、不查库)+ 长命 Refresh(存 Redis、能作废、低频刷新)。既要安全又要体验,是最主流的工程解法。
  • 多端登录 / 踢下线:靠 Redis 维护每个用户的”在线登录表”,控制”同时几端""挤掉旧的”。本质是”服务端掌控哪些令牌还算数”。
  • 多端登录、踢下线、退出、封号是同一类问题,都要求服务端存状态——纯无状态 JWT 做不到。
  • SSO:把认证从各业务系统抽出来交给统一的”认证中心”,一次登录、处处通行;OAuth2 / OIDC 是其标准协议,“第三方账号登录”是其典型应用。
  • 贯穿全篇的一条主线:要多少”控制力”,就得存多少”状态”。 这是登录架构里永恒的权衡。

最后一章,我们用一张决策树和一份避坑清单,把这十章的内容收口。


上一章 ← 08 - 绕不开的安全问题 | 下一章 → 10 - 总结与决策树 | 回到 README 目录