IWish Auth开发者文档
V1 Alpha GitHub

跨 App SSO

授权码、PKCE、App session 和登出边界

IWish Auth 使用 Portal 作为统一登录入口,业务 App 使用 OAuth 风格授权码和不透明 App session。当前协议不是公开标准 OIDC issuer,业务 App 应通过 SDK 接入,避免依赖 Supabase token 细节。

1. 授权流程

App /auth/login
  -> 生成随机 state 和 PKCE verifier/challenge
  -> 将 state/verifier 写入 10 分钟 HttpOnly cookie
  -> 跳转 Portal authorize URL
Portal
  -> 恢复统一登录或要求飞书/邮箱登录
  -> 用户选择授权组织
  -> POST /v1/sso/authorize
App /auth/callback
  -> 校验 state
  -> POST /v1/sso/token 交换一次性 code
  -> 设置本 App HttpOnly session cookie
业务请求
  -> GET /v1/sso/session 解析上下文

2. Authorization Code

  • 有效期 60 秒。
  • 只能消费一次。
  • clientId、精确 redirectUri 和 PKCE challenge 绑定。
  • 数据库使用原子 RPC 消费,避免并发重放。

业务 App 不得记录 code,也不得在浏览器调用 token endpoint。

3. PKCE 和 State

只允许 S256codeVerifierstate 必须是密码学安全随机值,保存在短时 HttpOnly、SameSite=Lax cookie。Callback 必须先校验 state,再交换 code。

缺少 state、state 不匹配、verifier 缺失都必须终止登录,不允许降级继续。

4. App Session

POST /v1/sso/token 返回 opaque accessToken。它不是 JWT,业务 App 不应自行解析。每个受保护请求通过 SDK 调用 GET /v1/sso/session 获取:

  • session:ID 和过期时间。
  • user:统一身份。
  • employee:飞书员工上下文或 null
  • organization:本次授权域。
  • app:当前 App。
  • rolespermissions:当前 App scoped 权限。
  • clientAssignments:当前有效客户项目分工。

5. 立即失效条件

以下状态变化会使后续 session introspection 失败或不再包含旧权限:

  • 用户、组织成员、组织或 App 被停用。
  • 飞书员工离职、冻结或不再有效。
  • App 角色被撤销。
  • OAuth client 被停用或轮换 secret。
  • 用户执行全局登出。
  • App session 被局部撤销或过期。

业务 App 可以使用最多 5 秒短缓存降低重复 introspection,但不得无限缓存身份和权限。

6. 登出模型

  • App 局部登出:POST /v1/sso/logout,删除本 App cookie。
  • Portal 全局登出:POST /v1/sso/logout-all,撤销全部 App sessions,再退出统一登录。
  • 单个 App 不得直接清理其他 App cookie。

7. 稳定错误码

sso_client_not_foundsso_client_disabledsso_redirect_uri_not_allowedsso_organization_not_allowedsso_app_not_allowedsso_invalid_clientsso_invalid_grantsso_session_invalidsso_session_expiredsso_session_revoked

401 表示登录/session 需要恢复;403 表示用户已登录但没有当前授权,不应循环重试登录。