1. OIDC协议基础

OpenID Connect (OIDC) 是构建在 OAuth 2.0 之上的身份认证层。OAuth 2.0 解决的是“授权”问题——允许第三方应用访问受保护资源;OIDC 则解决“认证”问题——让第三方应用验证用户身份并获取用户的基本信息。在生产环境中,OIDC 是单点登录 (SSO)、API 网关认证、微服务间身份传递的基石。

1.1 核心概念与角色

OIDC 协议定义了四个核心角色,理解它们之间的交互是诊断令牌刷新与缓存失效问题的前提:

角色 英文名称 职责说明
终端用户 End-User 需要被认证的自然人,持有浏览器或原生客户端
依赖方 Relying Party (RP) 需要验证用户身份的 Web 应用或移动 App,即你的业务系统
OpenID 提供者 OpenID Provider (OP) 负责认证用户并颁发令牌的授权服务器,如 Keycloak、Okta、Auth0
用户信息端点 UserInfo Endpoint OP 提供的受保护 API,RP 使用 Access Token 获取用户声明
故障排查要点: 在缓存失效场景中,RP 与 OP 之间的时钟偏差、令牌签名密钥轮换、以及 UserInfo 端点的响应延迟,是导致认证失败最常见的三个根因。

1.2 ID Token 与 Access Token 的区别

这是 OIDC 中最容易混淆的一组概念。两者在格式、用途、生命周期和验证方式上存在本质差异:

对比维度 ID Token Access Token
格式 JWT (JSON Web Token),必须包含标准声明 JWT 或 opaque(不透明字符串),由 OP 决定
用途 证明用户身份,供 RP 本地验证 授权访问受保护资源(如 UserInfo、业务 API)
接收方 RP(客户端应用) 资源服务器(Resource Server)
验证方式 RP 使用 OP 的公钥本地验证签名和声明 资源服务器调用 OP 的 introspection 端点或本地验证 JWT
生命周期 通常较短(几分钟到几小时),不可刷新 可长可短,支持通过 Refresh Token 轮换
包含信息 iss、sub、aud、exp、iat、nonce 等认证声明 scope、client_id、授权范围、可能包含用户标识
常见陷阱: 很多开发者在缓存 Access Token 时,错误地将 ID Token 也一并缓存并用于后续请求的用户身份识别。ID Token 过期后不应再被信任,必须通过 Refresh Token 流程重新获取。

1.3 授权码流程(Authorization Code Flow)

授权码流程是 OIDC 中最安全、最常用的流程,适用于有后端服务器的 Web 应用。该流程通过一个临时的授权码(Authorization Code)来交换令牌,确保 Access Token 和 ID Token 不会暴露在浏览器端。

OIDC 授权码流程(Authorization Code Flow) 终端用户 依赖方 (RP) OpenID 提供者 ① 访问应用 ② 认证请求 ③ 用户认证 ④ 授权码 (code) ⑤ 授权码 + client_secret ⑥ ID Token + Access Token ⑦ Access Token ⑧ 用户声明 ⑨ 建立会话 关键安全特性: 授权码是临时凭证(通常 1-2 分钟有效),必须结合 client_secret 在服务端交换令牌,防止中间人窃取令牌。
缓存策略建议: 在授权码流程中,RP 应缓存从 UserInfo 端点获取的用户声明,而不是缓存 ID Token。声明缓存时间建议设置为 Access Token 有效期的 80%,避免令牌过期后仍使用陈旧数据。

1.4 隐式流程(Implicit Flow)

隐式流程是 OIDC 的早期流程,专为纯前端应用(如浏览器中的 JavaScript SPA)设计。该流程直接返回 Access Token 和 ID Token,跳过了授权码交换步骤。由于令牌直接暴露在 URL 片段中,安全性较低,OAuth 2.0 Security BCP (RFC 9700) 已不推荐使用,建议使用授权码流程 + PKCE 替代。

OIDC 隐式流程(Implicit Flow) 终端用户 浏览器 (SPA) OpenID 提供者 ① 访问应用 ② 认证请求 ③ 用户认证 ④ ID Token + Access Token ⑤ 建立会话 安全风险: 令牌通过 URL 片段 (#) 传递,可能被浏览器历史记录、Referer 头、日志系统泄露。现代应用应使用授权码流程 + PKCE。

1.5 流程对比与选型建议

对比维度 授权码流程 隐式流程
适用场景 Web 应用(有后端)、移动 App、Native 应用 纯浏览器 SPA(已不推荐)
令牌暴露 令牌在服务端交换,不暴露给浏览器 令牌直接暴露在浏览器 URL 片段中
安全性 高,支持 client_secret 和 PKCE 低,无法安全存储 client_secret
Refresh Token 支持,可获取 Refresh Token 不支持,无法刷新令牌
当前推荐度 强烈推荐 已弃用,建议迁移