认证与令牌
开放接口同时校验 Bearer accessToken 和 本次请求签名。获取 accessToken 的接口本身也必须签名,但不携带已有令牌。
两类请求
| 内容 | 获取 accessToken | 业务接口 |
|---|---|---|
| 路径 | POST /open/v1/auth/token | 其余已列出的 /open/v1 业务路径 |
X-App-Id | 必填 | 必填 |
X-Timestamp | 必填,Unix 秒 | 必填,Unix 秒 |
X-Sign | 必填,64 位小写 HMAC-SHA256 | 必填,64 位小写 HMAC-SHA256 |
Authorization | 不允许携带 | Bearer <access_token> |
| 请求体 | 必须完全为空 | GET 为空;POST 为 UTF-8 JSON |
| 查询参数 | 不允许 | 按对应接口声明提供 |
凭据名称在控制台显示为「密钥」。它就是签名公式中的 appSecret;不需要另建证书、API v3 密钥或回调专用密钥。
令牌有效期
正常有效期为 7200 秒。如果租户更早到期,令牌会在租户到期时失效。因此应以本次响应的 expires_in 和 expires_at 为准。
响应示例:
json
{
"code": 0,
"message": "",
"data": {
"access_token": "SERVER_GENERATED_ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 7200,
"expires_at": "2026-09-08T10:00:00Z"
}
}access_token 是不带填充的 Base64URL 字符串,当前编码 32 个随机字节。将它作为不透明字符串保存和发送,不解析、不修改、不附加引号。没有 refreshToken 接口。
新令牌会撤销旧令牌
每次获取令牌验证成功后,平台都会替换该租户的当前令牌。上一个令牌立即失效,包括使用相同 appID、时间戳和签名重复获取的情况。
以下操作也会使旧令牌不能继续使用:
- 租户密钥被重置。
- 租户停用、删除或到期。
- 令牌自身到期。
租户重新启用不会恢复旧令牌,客户端需要重新获取。
多实例应用如何缓存
由你的服务端统一管理一份租户令牌:
- 获取成功后,在共享缓存中保存令牌和实际过期时间。
- 多个业务实例使用同一份缓存,不各自重新获取。
- 刷新时使用互斥锁,让一个实例完成替换,再原子更新共享缓存。
- 业务请求拿到最新令牌后,重新生成时间戳和签名。
不要让两个定时刷新程序反复获取令牌,否则它们会互相撤销刚获得的令牌。示例客户端刻意不提供静默刷新;发生 401 时,先确认是否过期、被替换、密钥不正确或签名错误。
签名时间与重放
所有签名请求的时间戳都必须在服务端时间 前后 300 秒以内,边界值可以通过。时间戳使用正整数字符串,不带前导零、不使用毫秒。
当前协议没有请求 nonce,也不按签名做一次性去重。时间窗口内相同签名可以再次验证;写入重复保护由 JSON request_id 提供。查看幂等规则
最小调用示例
下载 client.mjs 后,将下面内容保存为 auth-demo.mjs。它展示如何获取并使用同一个令牌,不打印令牌本身。
js
import { Client } from './client.mjs';
const client = new Client(
process.env.GUIJI_BASE_URL,
process.env.GUIJI_APP_ID,
process.env.GUIJI_APP_SECRET
);
const issued = await client.issueToken();
// 实际应用在这里把 issued 原子保存到共享缓存。
const dashboard = await client.call(
issued.access_token, 'GET', '/open/v1/dashboard', {}, null
);
console.log(JSON.stringify(dashboard, null, 2));接口的详细请求约束和限频见获取 accessToken。