获取渠道 Token
渠道平台 Token 用于 开户、查询、延期和充值,后续请求使用 token: {platformToken}。获取方式取决于渠道已开通的协议,两种方式的 secret 含义不同。
接入前准备
本页只负责获得“可管理渠道下租户”的平台身份。它不是租户 API Key,也不能直接用于租户内员工操作。
| 交付项 | 普通方式 | V2 签名方式 |
|---|---|---|
| 应用标识 | 渠道 appid | 渠道 appid,需匹配约定前缀 |
| 服务端密钥 | 固定 secret | HMAC 共享密钥;不直接作为请求 secret 发送 |
| 调用方法 | GET + Query | POST + JSON |
| 重放保护 | 按已交付的普通协议 | 秒级时间窗口 + nonce + 签名 |
| 适用条件 | 已开通普通渠道 | 已开通 V2 渠道,双方时间同步 |
请让部署方明确你所属的接入方式;不能把固定 secret 填进 V2 请求,也不能将 AES 租户契约密钥用于 HMAC。
V2 调用时序
窄屏下可横向滚动查看时序图。
先换取凭据,再调用业务接口。Token 获取成功与开户成功是两个独立的业务结果,均须检查 code。
普通渠道
GET /openapi/partner/access/getToken
| Query 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appid | string | 是 | AIS 分配的普通渠道应用标识 |
secret | string | 是 | 该渠道应用的固定密钥 |
curl --get "${BASE_URL}/openapi/partner/access/getToken" \
--data-urlencode "appid=${PARTNER_APP_ID}" \
--data-urlencode "secret=${PARTNER_SECRET}"
此接口沿用 Query 凭据协议,应在服务端调用并避免记录完整请求 URL。
特殊渠道 V2 签名认证
POST /openapi/partner/access/v2/getToken,Content-Type: application/json。
适用于已与 AIS 开通特殊渠道协议的集成方。双方先安全交换 appid、允许的 appid 前缀和 HMAC 共享密钥;本文不提供任何环境的实际密钥。
| JSON 字段 | 类型 | 必填 | 约束 |
|---|---|---|---|
appid | string | 是 | 非空,最长 128 字符,匹配约定前缀 |
secret | string | 是 | 非空,最长 512 字符;格式为 timestamp.nonce.signature |
签名计算:
timestamp = 当前 Unix 秒级时间戳
nonce = 每次请求新生成的随机字符串
content = appid + "\n" + timestamp + "\n" + nonce
signature = Base64UrlWithoutPadding(HMAC-SHA256(UTF8(sharedSecret), UTF8(content)))
secret = timestamp + "." + nonce + "." + signature
content 的分隔符是两个真实换行符。时间戳与服务端时间差不超过 300 秒,不能传毫秒。同一 nonce 在有效窗口内只能使用一次;重试获取 Token 时应重新生成 nonce 和签名。
Node.js 服务端示例:
const { createHmac, randomUUID } = require("node:crypto");
function createPlatformCredential(appid, sharedSecret) {
const timestamp = String(Math.floor(Date.now() / 1000));
const nonce = randomUUID().replace(/-/g, "");
const content = [appid, timestamp, nonce].join("\n");
const signature = createHmac("sha256", sharedSecret)
.update(content, "utf8")
.digest("base64url");
return { appid, secret: [timestamp, nonce, signature].join(".") };
}
// 在服务端将返回对象 JSON 序列化后,POST 到 /openapi/partner/access/v2/getToken。
// 参数使用部署方交付的 appid 和 HMAC 共享密钥。
签名输入的精确约定
| 项目 | 规则 | 常见错误 |
|---|---|---|
| 时间戳 | 当前 Unix 秒的十进制文本 | 使用毫秒、时区日期字符串或固定示例值 |
| nonce | 每次请求重新生成;示例使用无短横线 UUID | 重试时重用已消费 nonce |
| 待签名文本 | appid、timestamp、nonce,以两个真实换行符连接,无尾部换行 | 把两个字符 \\n 当成换行;多加空格 |
| 密钥字节 | HMAC 共享密钥文本的 UTF-8 字节 | 未经约定再次做 Base64 解码 |
| 输出 | HMAC-SHA256 后 Base64Url,不保留 padding | 使用十六进制、普通 Base64 或保留 = |
| 请求 secret | 三段以英文句点连接 | 直接发送共享密钥或对整个 JSON 签名 |
发送签名请求
把上面函数生成的完整 JSON 保存为服务端临时请求体,下面用 V2_REQUEST_JSON 表示其内容。不要在终端历史里粘贴生产密钥。
curl --request POST "${BASE_URL}/openapi/partner/access/v2/getToken" \
--header "Content-Type: application/json" \
--data "${V2_REQUEST_JSON}"
响应与后续调用
两种获取方式返回相同字段:
{
"code": 8200,
"message": "SUCCESS",
"data": {
"token": "REPLACE_WITH_PLATFORM_TOKEN",
"expireTime": 604800
}
}
响应字段
| 字段 | JSON 类型 | 说明 |
|---|---|---|
code | integer | 8200 表示本次认证成功 |
message | string | 状态提示,不能依赖固定文案 |
data | object | 平台认证结果 |
data.token | string | 不透明的平台 Token,完整保存;后续放入 token 请求头,不加 Bearer |
data.expireTime | integer | 有效期秒数;普通方式与 V2 的口径区别见下文 |
expireTime 的单位是秒。V2 返回实际剩余有效期;普通渠道旧接口当前固定返回 604800,实际会话仍受部署配置约束。对接方使用返回值安排刷新,同时处理提前失效,不要把固定数值当成所有环境的保证。
curl --get "${BASE_URL}/openapi/partner/account/query" \
--header "token: ${PLATFORM_TOKEN}" \
--data-urlencode "name=partner_tenant_001"
特殊渠道未启用、appid 不匹配、签名错误、时间超窗或 nonce 重放会导致认证失败。参数错误和凭据错误按 错误编码 处理。
平台 Token 不代表租户内用户。要初始化组织、员工或知识库,请继续阅读 租户用户契约。
缓存、刷新与故障处理
建议以“服务地址 + appid”隔离服务端 Token 缓存;不跨环境或渠道复用。V2 根据获取完成时间及返回剩余时间计算本地缓存截止点,并预留网络与时钟误差。不要每个业务请求都重新获取 Token。
| 现象 | 核对顺序 | 是否可重试 |
|---|---|---|
| 参数错误 | JSON 字段、长度、三段 secret 格式 | 修正后重试 |
| 签名认证失败 | 接入是否启用 → appid/前缀 → HMAC 密钥 → 编码与换行 | 修正后生成新 nonce |
| 时间超窗 | 双方时间同步、秒/毫秒、代理排队时长 | 校准后重新签名 |
| nonce 重放 | 重试机制是否原样重发请求体 | 生成全新 nonce 与签名 |
| 业务调用凭据过期 | 请求头是否为 token、是否跨环境使用、缓存是否到期 | 获取新 Token;写业务先确认上次结果 |
| Token 有效但租户查询失败 | 租户编码、渠道归属、业务权限 | 不通过重复刷新 Token 解决 |
服务端未提供本页所定义的 refresh_token。刷新指重新调用获取接口。对于充值或开户,刷新凭据后不能直接重放一个结果未知的写请求;先按 租户管理 的规则核对状态。