usr-login-用户登录功能

问题

一个web应用,我要实现一次登录访问同源【同一域名】下的其他页面不会要求重新登录

要实现这个功能,有哪些做法?

技术演变

Step1: 原始(1995~2005)

技术组合:

  • 用户名+密码
  • 服务端Seasion
  • Cookie

工作方式

登录成功 → 生成 session_id → 写入 Cookie → 服务端内存/数据库存状态

优点:

✅ 简单 ✅ 安全模型直观

致命问题:

❌ 扩容困难❌ 跨系统无法共享❌ 微服务不适合

Seasion-Cookie


Step2: 集中会话 + 缓存(2005~2012)

技术组合:

  • Session + Redis/Memcached
  • 负载均衡

工作方式

所有服务器共享 session 存储

解决:

✅ 扩容问题

❌ 仍然是有状态系统 ❌ 跨公司/跨系统依然难


Step3: Token 时代(2012~至今)

开始出现:

OAuth2(授权框架)

解决:

  • 第三方登录(微信、Google、GitHub)
  • 资源访问授权

JWT(无状态身份载体)

解决:

  • 分布式认证
  • 微服务身份传播
  • SSO

JWT 成为 OAuth2 的默认 Access Token 格式。

JWT-介绍


Step4:SSO & 身份中心(2015~至今)

代表系统:

  • Keycloak
  • Auth0
  • Okta
  • Azure Entra ID(Azure AD)

技术栈:

  • OAuth2
  • OpenID Connect (OIDC)
  • JWT
  • 公钥验签(JWKS)

解决: ✅ 登录一次,多系统通行 ✅ 企业级权限管理 ✅ 多因子认证

SSO介绍


Step5:BFF + Zero Trust(2019~至今)

引入:

  • BFF(Backend For Frontend)
  • 短 JWT + Refresh Token
  • mTLS / DPoP / 风控

解决: ✅ 前端安全 ✅ 自动续期 ✅ 微服务复杂度隔离 ✅ 云原生安全架构

总结技术

时代 技术 解决什么 痛点
早期 Cookie + Session 基础登录 扩展难
中期 Session + Redis 横向扩展 仍有状态
Token JWT 无状态认证 失效难
SSO OAuth2 + OIDC 多系统登录 架构复杂
现代 JWT + Refresh + BFF 安全 + 无感续期 设计要求高

技术选型推荐

为了实现免密登录,可以采用的方案

方案 1(最推荐、也最简单稳):Cookie + Server Session(Redis/内存)

适合:你描述的“站内保持登录”场景。

怎么做

  • 登录成功:服务端生成 session_id
  • session_id 写到 HttpOnly Cookie
  • 服务端保存 session(内存或 Redis),里面存 user_id、过期时间
  • 每个页面/接口请求都自动带 cookie,服务端查 session 就知道是谁

优点

  • 实现最简单
  • 逻辑最直观
  • “登录态在站内持续”非常自然
  • 想加“退出登录/失效”也很容易

缺点

  • 服务端是有状态(但你系统不复杂,这不是问题)
  • 多服务/微服务时需要共享 session 存储(Redis 一把就解决)

对“只是站内免重复登录”的系统,这反而是最合适的工程方案。

方案 2(也常用):短 Access JWT + Refresh Cookie(但不做复杂风控)

适合:你以后可能会有 API / 移动端 / 微服务。

你可以做得很轻量:

  • access JWT:比如 1 天(甚至 7 天)
  • refresh:可选(不做也行)
  • token 放 HttpOnly Cookie 或 Authorization header

但注意:如果你不做 refresh/session 存储,就不能主动失效(用户只能等过期)。

方案 3(最偷懒但风险大):长效 JWT(30 天)直接当登录态

只有在:内部系统、风险低、能接受泄露后 30 天有效 才考虑。

  • 你可以把 JWT 放 HttpOnly Cookie
  • 服务端每次验签即可

缺点是:

  • 无法主动失效(除非你引入黑名单/版本号,那又复杂了)
  • token 泄露后可用到过期
github