Deep Dive | src/utils/auth.ts 2002 行 — 鉴权核心(API key + OAuth + AWS + GCP + 订阅)¶
重要性:⭐⭐⭐(鉴权中心——5 种鉴权方式:API key / OAuth / AWS Bedrock / GCP Vertex / keychain) 真实位置:
src/utils/auth.ts(2002 行) 角色:管理所有鉴权方式——Anthropic API key、Claude AI OAuth、AWS Bedrock、GCP Vertex、macOS keychain 关联:topics/deep-dive-claude-api.md、topics/deep-dive-mcp-auth.md
1. 文件全景¶
auth.ts (2002 行)
│
├── 行 1-100 :imports + 常量
│ ├── DEFAULT_API_KEY_HELPER_TTL (5 min)
│ ├── isManagedOAuthContext
│ └── isAnthropicAuthEnabled (export, 行 100, ~50 行)
│
├── 行 153-220:source 决策
│ ├── getAuthTokenSource (export, 行 153, ~55 行)
│ ├── ApiKeySource type (行 208)
│ ├── getAnthropicApiKey (export, 行 214)
│ └── hasAnthropicApiKeyAuth (export, 行 219)
│
├── 行 226-355:getAnthropicApiKeyWithSource (export, 行 226, ~130 行)
│
├── 行 355-470:API key helper
│ ├── getConfiguredApiKeyHelper (export, 行 355)
│ ├── isApiKeyHelperFromProjectOrLocalSettings (行 366)
│ ├── getConfiguredAwsAuthRefresh (行 383)
│ ├── isAwsAuthRefreshFromProjectSettings (export, 行 391)
│ ├── getConfiguredAwsCredentialExport (行 408)
│ ├── isAwsCredentialExportFromProjectSettings (export, 行 416)
│ ├── calculateApiKeyHelperTTL (export, 行 435, ~30 行)
│ └── getApiKeyHelperElapsedMs (export, 行 464)
│
├── 行 469-605:API key helper 执行
│ ├── getApiKeyFromApiKeyHelper (export, 行 469, ~32 行)
│ ├── _runAndCache (行 501, ~37 行)
│ ├── _executeApiKeyHelper (行 538, ~43 行)
│ ├── getApiKeyFromApiKeyHelperCached (export, 行 581)
│ ├── clearApiKeyHelperCache (export, 行 585)
│ └── prefetchApiKeyFromApiKeyHelperIfSafe (export, 行 591, ~15 行)
│
├── 行 606-820:AWS Bedrock
│ ├── DEFAULT_AWS_STS_TTL (1h)
│ ├── runAwsAuthRefresh (行 612, ~36 行)
│ ├── AWS_AUTH_REFRESH_TIMEOUT_MS (3 min)
│ ├── refreshAwsAuth (export, 行 650, ~55 行)
│ ├── getAwsCredsFromCredentialExport (行 705, ~80 行)
│ ├── refreshAndGetAwsCredentials (memoizeWithTTLAsync, 行 787, ~22 行)
│ ├── clearAwsCredentialsCache (export, 行 809)
│ └── getConfiguredGcpAuthRefresh + isGcpAuthRefreshFromProjectSettings
│
├── 行 841-1050:GCP Vertex
│ ├── GCP_CREDENTIALS_CHECK_TIMEOUT_MS (5s)
│ ├── checkGcpCredentialsValid (export, 行 847, ~22 行)
│ ├── DEFAULT_GCP_CREDENTIAL_TTL (1h)
│ ├── runGcpAuthRefresh (行 875, ~40 行)
│ ├── GCP_AUTH_REFRESH_TIMEOUT_MS (3 min)
│ ├── refreshGcpAuth (export, 行 917, ~57 行)
│ ├── refreshGcpCredentialsIfNeeded (memoizeWithTTLAsync, 行 974)
│ ├── clearGcpCredentialsCache (export, 行 983)
│ ├── prefetchGcpCredentialsIfSafe (export, 行 994, ~30 行)
│ └── prefetchAwsCredentialsAndBedRockInfoIfSafe (export, 行 1023, ~28 行)
│
├── 行 1051-1200:macOS keychain
│ ├── getApiKeyFromConfigOrMacOSKeychain (memoize, 行 1051, ~38 行)
│ ├── isValidApiKey (行 1089)
│ ├── saveApiKey (export, 行 1094, ~68 行)
│ ├── isCustomApiKeyApproved (export, 行 1162)
│ ├── removeApiKey (export, 行 1170, ~15 行)
│ └── maybeRemoveApiKeyFromMacOSKeychain (行 1185)
│
├── 行 1194-1340:OAuth token 存储
│ ├── saveOAuthTokensIfNeeded (export, 行 1194, ~60 行)
│ ├── getClaudeAIOAuthTokens (memoize, 行 1255, ~52 行)
│ ├── clearOAuthTokenCache (export, 行 1308)
│ └── invalidateOAuthCacheIfDiskChanged (行 1320, ~23 行)
│
├── 行 1343-1565:401 处理
│ ├── pending401Handlers (Map, 行 1343)
│ ├── handleOAuth401Error (export, 行 1360, ~13 行)
│ ├── handleOAuth401ErrorImpl (行 1373, ~26 行)
│ ├── getClaudeAIOAuthTokensAsync (export, 行 1399, ~28 行)
│ ├── checkAndRefreshOAuthTokenIfNeeded (export, 行 1427, ~20 行)
│ └── checkAndRefreshOAuthTokenIfNeededImpl (行 1447, ~117 行)
│
├── 行 1564-1740:subscription types
│ ├── isClaudeAISubscriber (export, 行 1564, ~16 行)
│ ├── hasProfileScope (export, 行 1580)
│ ├── is1PApiCustomer (export, 行 1586, ~28 行)
│ ├── getOauthAccountInfo (export, 行 1615)
│ ├── isOverageProvisioningAllowed (export, 行 1623, ~24 行)
│ ├── hasOpusAccess (export, 行 1647, ~15 行)
│ ├── getSubscriptionType (export, 行 1662, ~17 行)
│ ├── isMaxSubscriber / isTeamSubscriber / isTeamPremiumSubscriber /
│ │ isEnterpriseSubscriber / isProSubscriber (export, ~5 行 each)
│ ├── getRateLimitTier (export, 行 1702, ~12 行)
│ ├── getSubscriptionName (export, 行 1714, ~18 行)
│ └── isUsing3PServices (export, 行 1732, ~10 行)
│
├── 行 1743-1855:OpenTelemetry
│ ├── getConfiguredOtelHeadersHelper (行 1743)
│ ├── isOtelHeadersHelperFromProjectOrLocalSettings (export, 行 1751, ~17 行)
│ ├── DEFAULT_OTEL_HEADERS_DEBOUNCE_MS (29 min)
│ └── getOtelHeadersFromHelper (export, 行 1770, ~70 行)
│
└── 行 1842-2002:account info
├── isConsumerPlan (行 1842)
├── isConsumerSubscriber (export, 行 1846)
├── UserAccountInfo type (行 1855)
├── getAccountInformation (export, 行 1863, ~48 行)
├── OrgValidationResult type (行 1911)
├── validateForceLoginOrg (export, 行 1923, ~80 行)
└── GcpCredentialsTimeoutError class (行 2002)
2. 5 种鉴权方式¶
| 方式 | API | TTL / 缓存 | 描述 |
|---|---|---|---|
| Anthropic API key | ANTHROPIC_API_KEY |
5 min helper TTL | 商业 API key |
| API key helper | apiKeyHelper |
5 min | 自定义 shell 命令 |
| Claude AI OAuth | claude.ai OAuth |
memoize | 订阅用户 |
| AWS Bedrock | CLAUDE_CODE_USE_BEDROCK |
1h STS TTL | AWS 用户 |
| GCP Vertex | CLAUDE_CODE_USE_VERTEX |
1h | GCP 用户 |
5 种 —— 涵盖所有可能的鉴权来源。
3. 优先级链(getAuthTokenSource, 行 153)¶
function getAuthTokenSource(): ApiKeySource {
// 1. macOS keychain
// 2. env ANTHROPIC_API_KEY
// 3. settings apiKey
// 4. apiKeyHelper
// 5. Claude AI OAuth
// 6. AWS Bedrock
// 7. GCP Vertex
}
优先级链 —— 按顺序找,找到就返回。
4. getAnthropicApiKeyWithSource — 130 行(行 226)¶
export function getAnthropicApiKeyWithSource(): { apiKey, source } | null {
// 1. macOS keychain
// 2. env
// 3. settings
// 4. helper
// 5. OAuth
// 6. 3P
}
130 行 —— 完整优先级链 + 来源追踪。
5. API Key Helper(7 个函数)¶
getConfiguredApiKeyHelper
isApiKeyHelperFromProjectOrLocalSettings
getApiKeyFromApiKeyHelper
_runAndCache
_executeApiKeyHelper
getApiKeyFromApiKeyHelperCached
clearApiKeyHelperCache
prefetchApiKeyFromApiKeyHelperIfSafe
8 个 —— 用户自定义 shell 命令生成 API key。
5 min TTL —— helper 调用不频繁。
6. AWS Bedrock(5 个函数)¶
runAwsAuthRefresh
refreshAwsAuth
getAwsCredsFromCredentialExport
refreshAndGetAwsCredentials (memoizeWithTTLAsync)
clearAwsCredentialsCache
prefetchAwsCredentialsAndBedRockInfoIfSafe
6 个 —— AWS STS 临时凭据 + Bedrock 信息预取。
DEFAULT_AWS_STS_TTL = 1h —— STS 临时凭据 1h 有效。
AWS_AUTH_REFRESH_TIMEOUT_MS = 3 min —— 刷新超时。
7. GCP Vertex(6 个函数)¶
checkGcpCredentialsValid
runGcpAuthRefresh
refreshGcpAuth
refreshGcpCredentialsIfNeeded (memoizeWithTTLAsync)
clearGcpCredentialsCache
prefetchGcpCredentialsIfSafe
6 个 —— GCP 凭据 + 刷新。
DEFAULT_GCP_CREDENTIAL_TTL = 1h —— GCP 凭据 1h 有效。
GCP_CREDENTIALS_CHECK_TIMEOUT_MS = 5s —— 验证 5s 超时。
8. macOS Keychain¶
getApiKeyFromConfigOrMacOSKeychain (memoize)
isValidApiKey
saveApiKey
isCustomApiKeyApproved
removeApiKey
maybeRemoveApiKeyFromMacOSKeychain
6 个 —— macOS keychain 集成。
关键 —— 仅 macOS 用 keychain(其他平台不存)。
9. OAuth Token 存储(4 个函数)¶
saveOAuthTokensIfNeeded
getClaudeAIOAuthTokens (memoize)
clearOAuthTokenCache
invalidateOAuthCacheIfDiskChanged
4 个 —— Claude AI OAuth token 存储 + 缓存。
memoize —— 单次 session 内不重复 IO。
10. 401 处理(5 个函数)¶
pending401Handlers (Map)
handleOAuth401Error
handleOAuth401ErrorImpl
getClaudeAIOAuthTokensAsync
checkAndRefreshOAuthTokenIfNeeded
checkAndRefreshOAuthTokenIfNeededImpl (~117 行)
6 个 —— 401 自动 token 刷新。
pending401Handlers Map —— 同一 token 401 时只触发一次刷新。
11. Subscription Types(11 个函数)¶
isClaudeAISubscriber
hasProfileScope
is1PApiCustomer
getOauthAccountInfo
isOverageProvisioningAllowed
hasOpusAccess
getSubscriptionType
isMaxSubscriber
isTeamSubscriber
isTeamPremiumSubscriber
isEnterpriseSubscriber
isProSubscriber
getRateLimitTier
getSubscriptionName
isUsing3PServices
15+ 个 —— 订阅类型 + 权限 + rate limit。
5 种 subscription: - Max - Team - Team Premium - Enterprise - Pro
12. OpenTelemetry Headers(3 个函数)¶
getConfiguredOtelHeadersHelper
isOtelHeadersHelperFromProjectOrLocalSettings
getOtelHeadersFromHelper (~70 行)
3 个 —— OpenTelemetry 自定义 headers。
DEFAULT_OTEL_HEADERS_DEBOUNCE_MS = 29 min —— 29 分钟防抖(避免 helper 调用太频繁)。
13. Account Info + Force Login¶
UserAccountInfo type
getAccountInformation (~48 行)
OrgValidationResult type
validateForceLoginOrg (~80 行)
GcpCredentialsTimeoutError
4 个 —— 账户信息 + org 验证。
14. 关键设计模式¶
14.1 5 种鉴权统一抽象¶
5 种方式 —— 不同入口,统一 getAnthropicApiKey*()。
14.2 优先级链¶
getAuthTokenSource —— 6 步优先级。
14.3 memoizeWithTTLAsync¶
3 个用 memoizeWithTTLAsync:
- refreshAndGetAwsCredentials
- refreshGcpCredentialsIfNeeded
- getApiKeyFromConfigOrMacOSKeychain
TTL = 1h —— AWS / GCP 凭据 1h 缓存。
14.4 pending401Handlers Map¶
401 去重 —— 同一 token 401 只触发一次刷新。
14.5 prefetch 预取¶
prefetchApiKeyFromApiKeyHelperIfSafe / prefetchGcpCredentialsIfSafe / prefetchAwsCredentialsAndBedRockInfoIfSafe
3 个 prefetch —— 启动后预取 3P 凭据。
14.6 5 min helper TTL¶
DEFAULT_API_KEY_HELPER_TTL = 5 min —— helper 调用适度。
14.7 1h 3P TTL¶
DEFAULT_AWS_STS_TTL = 1h / DEFAULT_GCP_CREDENTIAL_TTL = 1h —— AWS/GCP 凭据 1h。
14.8 3 min refresh timeout¶
AWS_AUTH_REFRESH_TIMEOUT_MS = 3 min / GCP_AUTH_REFRESH_TIMEOUT_MS = 3 min —— 3 分钟刷新上限。
14.9 29 min OTEL debounce¶
DEFAULT_OTEL_HEADERS_DEBOUNCE_MS = 29 min —— 防止 helper 调用太频繁(29 而不是 30 避免同时刷新)。
14.10 macOS keychain 专属¶
maybeRemoveApiKeyFromMacOSKeychain —— 仅 macOS。
14.11 Source 追踪¶
ApiKeySource enum + getAnthropicApiKeyWithSource —— 知道 key 从哪来(debug 友好)。
15. 复杂度分析¶
| 维度 | 数字 |
|---|---|
| 总行数 | 2002 |
| 鉴权方式 | 5 |
| 公开函数 | 50+ |
| memoize 包装 | 3 |
| 预取 | 3 |
| 401 处理 | 6 |
16. 性能特征¶
16.1 首次鉴权¶
- API key:< 1ms(env 读)
- Helper:~10-50ms(shell 调用)
- OAuth:~10-50ms(keychain 读)
- AWS:~100-500ms(STS 调)
- GCP:~100-500ms(metadata server 调)
16.2 缓存¶
- 5 min helper TTL
- 1h 3P TTL
- memoize —— session 内不重复
16.3 Prefetch¶
启动后预取 3P 凭据 —— 不阻塞首屏。
17. 与其他文件的关系¶
auth.ts
├──→ keychain (macOS)
├──→ env vars
├──→ settings
├──→ AWS STS
├──→ GCP metadata server
├──→ claude.ai OAuth
└──→ Claude API
18. 关键洞察¶
18.1 5 种鉴权 = 全部可能入口¶
商业 API / 自定义 helper / Claude 订阅 / AWS / GCP —— 不漏一个。
18.2 优先级链是"用户友好"¶
env > settings > helper > OAuth —— local config 优先。
18.3 5 min helper TTL¶
helper 调用不频繁 —— 保护 helper 进程。
18.4 1h 3P TTL¶
AWS / GCP 凭据 1h 缓存 —— 不超时。
18.5 pending401Handlers 去重¶
同一 token 401 只刷新一次 —— 防止 refresh storm。
18.6 29 min OTEL debounce¶
29 而不是 30 —— 避免同时刷新。
18.7 macOS keychain 专属¶
其他平台不用 keychain —— 平台相关。
18.8 Source 追踪¶
getAnthropicApiKeyWithSource —— 知道 key 哪来(debug 友好)。
18.9 15+ subscription 函数¶
Max / Team / Pro / Enterprise —— 商业产品分级。
18.10 3 个 prefetch¶
AWS / GCP / helper —— 启动后不阻塞首屏。
19. 阅读建议¶
- 看 5 种鉴权常量(行 81, 606, 869, 1768)—— TTL
- 看 getAuthTokenSource(行 153)—— 优先级链
- 看 getAnthropicApiKeyWithSource(行 226)—— 完整链
- 看 AWS 系列(行 612-820)—— AWS 集成
- 看 GCP 系列(行 841-1050)—— GCP 集成
- 看 subscription 函数(行 1564-1740)—— 商业产品
20. 与其他深度拆解的关系¶
| 文件 | 关系 |
|---|---|
claude.ts |
用 auth.ts 的 token |
mcp/auth.ts |
MCP 自己的 auth(不同) |
analytics/ |
用 account info |
21. 阅读清单¶
- ✅ 看 5 种鉴权常量(行 81, 606, 869, 1768)
- ✅ 看 getAuthTokenSource(行 153)
- ✅ 看 getAnthropicApiKeyWithSource(行 226)
- ✅ 看 AWS / GCP 系列
- ✅ 看 subscription 函数
- 📌 对照 topics/deep-dive-mcp-auth.md 区分
22. 练习任务¶
- 数鉴权方式(grep)—— 5
- 数 memoize 包装(grep)—— 3
- 数 subscription 函数(grep
is.*Subscriber)—— 5+ - 画鉴权优先级链 —— keychain > env > settings > helper > OAuth
- 手写迷你 auth(~50 行)—— env + helper + 1 个 prefetch
- 思考:auth.ts 是否太"全"?能否拆成 5 个文件?