使用 OAuth 2.0 实现单点登录(SSO)

使用 OAuth 2.0 实现单点登录(SSO)时,多个子应用共享同一登录状态,可以通过以下方式实现


场景背景

  • 平台统一认证服务器(IdP):如 auth.example.com
  • 子应用 A 和 B:如 appA.example.comappB.example.com
  • 目标:用户在子应用 A 登录后,在同一浏览器中访问子应用 B 时,无需重新登录。

使用 OAuth 2.0 的模式

授权码模式(Authorization Code Grant) 是最适合此场景,因为:

  1. 支持前后端分离: Token 不直接暴露在浏览器中,安全性高。
  2. 适合浏览器登录场景: 子应用 A 和 B 都可以通过重定向完成授权。
  3. 支持 SSO: 登录状态通过浏览器的 Cookie 在认证服务器(IdP)共享。

完整流程

以下是基于授权码模式的 SSO 实现流程:


1. 用户访问子应用 A
  • 场景:用户首次访问 appA.example.com
  • 行为
    1. 子应用 A 检查用户是否已登录(通过存储在浏览器的 Cookie 或 Token)。
    2. 如果未登录,子应用 A 重定向用户到统一的认证服务器(auth.example.com),并附带以下参数:
      GET https://auth.example.com/oauth/authorize
      ?response_type=code
      &client_id=appA
      &redirect_uri=https://appA.example.com/callback
      &scope=read_profile
      &state=random_string_for_csrf_protection
      
      • response_type=code:请求授权码。
      • client_id=appA:标识子应用 A。
      • redirect_uri:授权后跳转的 URL。
      • scope:请求访问的权限范围。
      • state:防止 CSRF 攻击的随机字符串。

2. 用户登录
  • 场景:用户在认证服务器 auth.example.com 上完成登录。
  • 行为
    1. 用户输入用户名和密码。
    2. 认证服务器验证成功后,在其域(auth.example.com)设置一个浏览器会话 Cookie,用于维护登录状态。
      • 这个 Cookie 是 HttpOnly、Secure 的,绑定到 auth.example.com,确保安全。

3. 子应用 A 获取 Access Token
  • 场景:用户登录后,认证服务器返回授权码给子应用 A。
  • 行为
    1. 认证服务器通过浏览器重定向用户到子应用 A 的回调地址:
      https://appA.example.com/callback?code=auth_code&state=random_string
      
    2. 子应用 A 后端使用授权码(auth_code)向认证服务器请求 Access Token:
      POST https://auth.example.com/oauth/token
      Content-Type: application/x-www-form-urlencoded
      
      grant_type=authorization_code
      code=auth_code
      redirect_uri=https://appA.example.com/callback
      client_id=appA
      client_secret=appA_secret
      
    3. 认证服务器验证后,返回 Access Token 和 ID Token:
      {
        "access_token": "access_token_value",
        "id_token": "id_token_value",
        "expires_in": 3600,
        "token_type": "Bearer"
      }
      
    4. 子应用 A 将 Access Token 存储在用户的浏览器(如 Cookie 或 Local Storage),以便后续 API 调用。

4. 用户访问子应用 B
  • 场景:用户在同一浏览器中访问 appB.example.com
  • 行为
    1. 子应用 B 检查用户是否已登录(本地无 Token)。
    2. 子应用 B 重定向用户到认证服务器的授权页面(流程类似子应用 A 的初始登录):
      GET https://auth.example.com/oauth/authorize
      ?response_type=code
      &client_id=appB
      &redirect_uri=https://appB.example.com/callback
      &scope=read_profile
      &state=random_string_for_csrf_protection
      

5. 认证服务器检测登录状态
  • 场景:用户已登录认证服务器。
  • 行为
    1. 认证服务器检查用户在其域的会话 Cookie,发现用户已登录,无需再次输入用户名和密码。
    2. 认证服务器直接生成授权码,并重定向用户回子应用 B:
      https://appB.example.com/callback?code=auth_code_for_appB&state=random_string
      

6. 子应用 B 获取 Access Token
  • 场景:子应用 B 使用授权码向认证服务器换取 Token。
  • 行为
    1. 后端请求 Access Token:
      POST https://auth.example.com/oauth/token
      Content-Type: application/x-www-form-urlencoded
      
      grant_type=authorization_code
      code=auth_code_for_appB
      redirect_uri=https://appB.example.com/callback
      client_id=appB
      client_secret=appB_secret
      
    2. 认证服务器返回 Token,子应用 B 存储并使用该 Token。

7. 用户已在子应用 B 登录
  • 子应用 B 使用 Token 访问受保护的资源(如用户信息 API)。
  • 用户感知为“无缝登录”。

关键技术点

  1. 共享会话依赖于认证服务器的 Cookie

    • 认证服务器(IdP)的会话 Cookie 是跨子应用 SSO 的核心。
    • 只要用户的浏览器在认证服务器域(auth.example.com)中有有效 Cookie,认证服务器即可快速判断用户登录状态。
  2. Token 隔离:

    • 子应用 A 和 B 使用各自的 Client ID 和 Secret,Token 互不影响。
    • 每个子应用的 Token 只对其自身有效,提升安全性。
  3. 安全措施:

    • 使用 state 防止 CSRF 攻击。
    • Token 存储和传输时加密。
    • 确保所有通信使用 HTTPS。

总结流程图

  1. 用户访问子应用 A → 未登录 → 跳转到认证服务器。
  2. 用户登录认证服务器 → 设置会话 Cookie。
  3. 认证服务器生成授权码 → 子应用 A 换取 Token。
  4. 用户访问子应用 B → 检测认证服务器会话 → SSO 无缝登录。

优点

  • 标准化(OAuth 2.0 授权码模式)。
  • 安全性高,防止 Token 泄露。
  • 子应用独立授权,隔离性好。
  • 无缝登录,提升用户体验。

适用场景

  • 适用于 SaaS 平台中多个子应用的单点登录场景。
  • 适合 Web 浏览器中用户操作的典型 SSO 场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT界的奇葩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值