首页
/ claude-code-router 网关 API 密钥完全指南:创建、过期控制与本地限额配置

claude-code-router 网关 API 密钥完全指南:创建、过期控制与本地限额配置

2026-09-08 20:08:13作者:柏廷章Berta

CCR(claude-code-router)网关对外统一暴露了一个本地控制面入口,所有接入的客户端都需要使用 API Key 完成身份认证。本文基于官方中文文档 API 密钥 系统讲解 CCR 桌面端中 API Key 的列表管理、创建编辑与高级限额配置,并结合仓库源码深入说明密钥生成格式、鉴权判定流程、过期语义与限流计数器的底层实现。读完本文,你将能够为不同客户端(本机 Claude Code、CI、团队成员)分配相互隔离、带过期时间和本地配额限制的独立访问密钥,并在出现 401 / 403 / 429 状态时快速定位原因。

一、API Key 在 CCR 中的作用与定位

CCR 把模型路由、供应商聚合、工具编排等能力收敛为单一网关。为了控制"谁能访问这个网关",CCR 要求每个请求都携带一个由网关签发的 API Key。这个 Key 有三个核心属性:

  1. 身份标识:通过 名称 区分客户端、团队、用途或自动化来源;
  2. 时效约束:可设置过期时间,过期后密钥立即失效;
  3. 本地限额:可为单个 Key 配置请求数 / token 数 / 图片数的本地上限,防止某一路流量挤占网关整体资源。

需要特别强调的是:限额是"本地"的,命中后只会拒绝或限制使用该 Key 的请求,并不会修改供应商侧(如 Anthropic、OpenAI)的配额。换句话说,这是一种网关侧的自保护与流量治理机制,而不是供应商账单管理工具。

桌面 UI 中所有 Key 的 CRUD 逻辑集中在 API 密钥视图组件,增删改的数据最终通过管理服务接口持久化(见 management-server.ts 中的 saveApiKeys),运行配置统一存放在 SQLite 配置数据库中(默认位置见 配置数据库位置:macOS/Linux 为 ~/.claude-code-router/config.sqlite,Windows 为 %APPDATA%\claude-code-router\config.sqlite)。

二、密钥列表页:每个字段意味着什么

进入桌面端"API 密钥"页面后,主要包含以下操作与字段:

字段 / 操作 说明
搜索 API 密钥 按名称或 Key 内容过滤列表,适用于 Key 数量较多时的快速定位。
添加 API 密钥 打开创建弹窗,生成一个新的客户端访问 Key。
名称 API Key 的显示名,用于区分客户端、团队、用途或自动化来源。
Key 脱敏后的访问 Key。点击 复制 API 密钥 可复制完整 Key。
过期 当前 Key 的过期时间。过期后客户端不能继续使用这个 Key 访问 CCR。
限制 当前 Key 的本地限额摘要。没有配置限额时显示"未配置限制"。
编辑 API 密钥 修改过期时间和限额。出于安全原因,已创建的 Key 本身不会重新明文展示。
移除 API 密钥 删除当前客户端访问 Key。删除后立即不能再用于请求。

从源码可以验证上述各列的呈现细节:

  • 脱敏规则:前端 maskApiKey 对长度大于 8 的 Key 保留前 18 位并以 *** 结尾;长度不足则整体显示为 ****。因此列表页永远不会完整展示明文 Key。
  • 搜索匹配apiKeyMatchesQuery 会同时匹配名称、完整 Key、脱敏 Key、Key 的 id、过期时间与限额摘要,所以即使只记得 Key 片段也能搜到对应条目。
  • 空态与提示:未配置任何 Key 时列表显示"No API keys configured",搜索无结果时显示"No matching API keys"。

列表行的操作按钮为编辑(铅笔图标)与移除(垃圾桶图标)。移除是即时生效的:后端在每次请求鉴权时动态读取持久化的 Key 集合,删除后该 Key 将不再出现在可用的鉴权候选列表中,后续携带该 Key 的请求会直接返回 401。

三、创建与编辑 API Key 的完整流程

点击"添加 API 密钥"后弹出的创建弹窗包含以下输入项:

字段 说明
名称 新 Key 的显示名。建议写成客户端或用途,例如 Claude Code - laptopCI 或团队名。
过期时间 选择 Key 的有效期:永不7 天30 天90 天自定义
过期于 选择 自定义 时出现,用于填写精确的过期日期和时间(datetime-local 选择器)。
API 密钥已创建 创建成功后的确认弹窗,这里会显示完整 Key。
请现在复制保存这个密钥,之后可能不会再次完整显示 提醒你立即复制 Key。关闭弹窗后,CCR 不会再次展示完整 Key。

密钥是怎么生成的

从实现上看,创建流程由 createGeneratedApiKey 完成,核心逻辑包括:

  • Key 值:由 generateApiKeyValue 生成,格式为 sk- 前缀 + 24 字节随机数做 Base64URL 编码(无填充),整体形如 sk-<约 32 个 URL 安全字符>
  • Key idkey_ 前缀 + 随机数,用于服务端限流计数器定位(见下文限额实现);
  • 随机源:优先使用 window.crypto.getRandomValuesrandomBase64Url),浏览器/Electron 场景下无法调用 crypto API 时才退化到 Math.random

过期时间如何换算

过期预设在 expiresAtFromApiKeyDraft 中被换算为绝对时间戳并序列化为 ISO 8601 字符串:

  • 永不:不写入 expiresAt 字段,等价于无限期;
  • 7 天 / 30 天 / 90 天:以当前时间为基准分别 +7 / +30 / +90 天;
  • 自定义:直接把用户输入的本地日期时间转换为 ISO 字符串。

创建新 Key 时默认预选"永不",自定义默认值落在创建时间 +30 天。后端在判断过期时同样解析该 ISO 字符串(见下文鉴权小节),因此前端设定与后端执行是同一份语义。

为什么编辑时看不到明文 Key

编辑弹窗只允许修改"过期时间"与"限额",而不展示、不修改 Key 本身。UI 层 updateApiKeyEditableConfig 会保留原 Key 的 idkeynamecreatedAt,仅覆盖 expiresAtlimits。这是刻意的安全设计:明文 Key 只在创建成功后的确认弹窗出现一次,之后再无读取路径,从而降低密钥被截获、泄露的风险。

四、高级设置:给单个客户端添加本地限额

"高级设置"用于给单个客户端 Key 添加本地限额。限额命中后,使用这个 Key 的客户端请求会被拒绝或限制;它不会修改供应商侧额度。

字段 说明
高级设置 展开或收起限额编辑区。
未配置限制 当前 Key 没有任何本地限额。
请求 按请求次数限制。
令牌 按 token 数量限制。
图片 按图片数量限制。
每分钟 限额窗口为 1 分钟。
每小时 限额窗口为 1 小时。
每天 限额窗口为 1 天。
添加限制 新增一条限额规则。
移除限制 删除当前限额规则。

在 UI 上,每条限额规则 =「指标(请求 / 令牌 / 图片)+ 窗口(每分钟 / 每小时 / 每天)+ 阈值数值」。你可以为同一个 Key 叠加多条规则(例如每分钟 60 次请求 + 每天 10 万 token),任意一条命中即触发限流。编辑已存在的 Key 时高级设置默认展开(defaultOpen),便于快速查看和修改既有限额。

限制在配置中的字段映射

前端会把"指标 × 窗口"组合转换为底层配置字段。映射函数 apiKeyLimitField 定义如下:

指标 \ 窗口 每分钟 每小时 每天
请求 rpm rph rpd
令牌 tpm tph tpd
图片 ipm iph ipd

配置在加载 / 展示时会走另一侧的归一化逻辑:apiKeyLimitRowsFromConfig 把已有的 rpm/tph 等字段反向还原成编辑表单的行,另有 maxRequests + windowMsmaxTokens + quotaWindowMs 这类可自定义窗口的兼容字段(如回落到分钟/天窗口)。底层归一化见 normalizeApiKeyLimits,所有数值必须为正整数才会被采纳。

五、底层原理:鉴权与限额是如何被执行的

理解了 UI 语义之后,再来看网关侧的执行逻辑,可以帮你预判各种状态码的来源。

鉴权判定流程

网关对所有请求统一走 authorize,流程如下:

  1. 读取可用 Key 集合;若当前没有任何可用 Key,直接返回 403(提示先保存一个网关 Key 或重启 CCR 自动生成);
  2. 从请求中提取 token:优先读取请求头,支持 Authorization: Bearer <key>x-api-key: <key> 两种形式(见 readAuthTokenBearer 前缀会被自动剥离);对于远程控制类接口,还会从查询参数 api_key / key 读取(readRemoteControlQueryAuthToken);
  3. 在 Key 集合中查找匹配项;匹配使用常数时间比较 timingSafeEqualconstantTimeEqual),避免通过响应耗时侧信道探测密钥;
  4. 若找到但已过期,返回 401,错误信息为 API key is expired.
  5. 未找到:带 token 返回 401 Invalid API key.,完全没带 token 返回 401 API key is missing.

因此你可以用状态码快速诊断:403 = 网关还没有任何 Key;401 + expired = Key 已过期;401 + invalid/missing = Key 不对或没带。

过期语义

过期判断 isApiKeyExpired 非常简单:若 Key 配置中没有 expiresAt 则不视为过期(即"永不");否则解析该 ISO 时间字符串并与当前时间比较,expiresAt <= now 即判为过期。所以创建 Key 时设置的"过期于"是精确到秒的硬性截止时刻,过期后无需任何额外操作,该 Key 立即可用性消失。

另外 CCR 还支持 Claude Code 的 OAuth/WIF 交换路径 /v1/oauth/tokenexchangeClaudeCodeWifToken):Claude Code 以 jwt-bearer 作为 grant type,把网关 API Key 当作断言(assertion)换取临时 access_token(有效期 3600 秒),换取时同样会做匹配与过期校验。这就是"用 API Key 认证 Claude Code 客户端"背后的标准协议实现。

限额如何计数与触发

在请求鉴权通过之后,网关会调用 reserveApiKeyLimits 预占限额。真正的窗口与规则逻辑在 window-limiter.ts

  • 规则展开limitRules 会把配置展开为一组规则。默认窗口换算为毫秒:每分钟 = 60_000、每小时 = 3_600_000、每天 = 86_400_000
  • 计数键:每个窗口计数器以 api-key|<key id>|<规则名>|<指标>|<窗口毫秒>|<窗口起点> 为键,天然把不同 Key、不同指标、不同窗口的用量隔离开(reserveApiKeyLimits);
  • 命中即拒:任意一条规则上"已用量 + 本次请求量 > 限额"时,请求返回 429,错误码为 rate_limit_exceeded,响应体附带 limitmetricrequestedusedwindow_ms 等明细,方便你判断到底是哪条规则被触发;
  • 先检查后扣减:所有规则全部放行后才真正累加计数,避免部分规则占用却最终失败产生"假消耗";
  • 内存窗口:计数器保留最近 2 个窗口并定期清理过期窗口(readWindowCounter),也就是说限额统计是进程内的、面向短时间窗口的本地治理。

token 与图片是如何"估算"的

"请求数"按 1 次请求 = 1 计数,而 token 与图片数则由 estimateLimitUsage 对请求体估算:

  • 只有 POST 且非空请求体会被统计,GET 等请求不消耗 token / 图片额度;
  • token 估算:输入部分取 messagessystemtools 内容的字符数总和,按约 4 字符 ≈ 1 token 折算;输出部分读取 max_tokens / max_output_tokens,缺省按 1024 计;最终总量下限为 1;
  • 图片估算:递归遍历请求体,识别 imageimage_urlinput_image 类型的 content 块及其变体字段,每出现一张图片计 1(countImageInputs)。

需要说明的是,这是网关在转发前做的近似估算(用于本地限额),并非供应商账单上的精确 token 计量,因此与最终计费数值可能存在差异。

六、最佳实践建议

  1. 一 Key 一用途:名称建议直接携带客户端与环境信息(如 Claude Code - laptopCI),列表按名称搜索即可快速定位问题来源;
  2. 短期密钥及时轮换:临时授权或共享给外部协作者时优先选择 7 天 / 30 天,避免出现永不过期的遗留密钥;需要精确截止时使用"自定义";
  3. 创建后立即复制:明文 Key 只在"API 密钥已创建"弹窗展示一次,务必当场保存到密码管理器,之后只能复制(前端仅保留脱敏值),无法重新查看;
  4. 限额从请求维度起步:先配置"每分钟请求数"这类粗粒度规则防止突发流量,再视情况叠加每日 token 上限;删除旧 Key 前确认没有正在运行的客户端仍在使用它,因为移除后该 Key 会立即失效;
  5. 结合状态码排查403 检查网关是否初始化了 Key,401 核对 Key 是否过期/正确及请求头格式(Authorization: Bearerx-api-key),429 则解析错误响应体中的 limit_name/metric/window_ms 找到被触发的限额规则。

相关实现与配置入口汇总:UI 界面 components/api-keys.tsx、Key 生成/换算/脱敏 shared/api-keys.ts、鉴权与 WIF auth/api-key-authorizer.ts、限额窗口计数 limits/window-limiter.ts、请求头读取 http/io.ts、Key 持久化 management-server.ts。如需在 Claude Code 等客户端中使用这些 Key 连接 CCR,可进一步参考中文文档中的 服务端/连接配置 系列页面。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391