获取签名
更新时间:2026-06-24
API访问域名
| 请求方式 | POST |
|---|---|
| base url | https://keyue.cloud.baidu.com/csp-service |
| 后缀接口 | /open/api/v3/auth/token |
说明
- 接口本身的控制器路径是
/open/api/v3/auth/token - 如果线上环境经过网关转发,最终访问地址可能会带上
/csp-service前缀,以实际网关暴露地址为准 -
该接口用于使用
AK/SK换取 OpenAPI 访问令牌accessToken- AK/SK是在百度智能云-安全认证中创建
- 客悦平台-管理中心-短信管理,该页面有一个已创建好的AK/SK,可以直接使用
-
调用时有两层校验:
- 网关前置鉴权:校验请求头中的签名、时间戳、防重放
- 业务鉴权:校验请求体中的
ak/sk是否存在、是否启用、是否匹配
-
accessToken返回后,后续业务接口通常通过Authorization: Bearer <accessToken>方式传递
请求参数
Header参数
| 名称 | 类型 | 必选 | 中文名 | 说明 |
|---|---|---|---|---|
| Host | string | 是 | 请求主机 | (如 ky-rd.cloud.baidu.com,会参与签名) |
| x-ak | string | 是 | AccessKey | |
| x-timestamp | string | 是 | Unix 毫秒级时间戳 | (13位,如 1772451000123) |
| x-nonce | string | 是 | 随机串 | (建议 16~64 字符) |
| x-signature | string | 是 | HMAC-SHA256 计算结果(hex) |
Body参数
| 名称 | 类型 | 必选 | 中文名 | 说明 |
|---|---|---|---|---|
| ak | string | 是 | AccessKey | |
| sk | string | 是 | SecretKey |
建议:x-ak 与 body 里的 ak 保持一致。
签名规则
签名算法(固定 v1)
- 算法:
HMAC-SHA256 - 密钥:
sk - 字符编码:
UTF-8 - 换行符:
\n(LF) - 签名输出:hex(建议小写;服务端支持大小写)
Canonical String(严格顺序)
Plain
1POST
2/open/api/v3/auth/token
3
4<host>
5<ak>
6<timestamp>
7<nonce>
8v1
说明:
- 第 3 行是空行,表示空 query string,不能省略
-
<host>取请求头Host的值,参与签名前建议先转小写 -
<ak>取请求头x-ak -
<timestamp>取请求头x-timestamp -
<nonce>取请求头x-nonce - 最后一行固定写死为
v1
签名计算公式:
Plain
1x-signature = hex( HMAC_SHA256(sk, canonicalString) )
签名算法示例
Java示例
Java
1import javax.crypto.Mac;
2import javax.crypto.spec.SecretKeySpec;
3import java.nio.charset.StandardCharsets;
4import java.time.Instant;
5import java.util.UUID;
6
7public class OpenApiTokenSign {
8 public static String sign(String host, String ak, String sk, String timestamp, String nonce) throws Exception {
9 String canonical = "POST\n"
10 + "/open/api/v3/auth/token\n"
11 + "\n"
12 + host.toLowerCase() + "\n"
13 + ak + "\n"
14 + timestamp + "\n"
15 + nonce + "\n"
16 + "v1";
17 Mac mac = Mac.getInstance("HmacSHA256");
18 mac.init(new SecretKeySpec(sk.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
19 byte[] out = mac.doFinal(canonical.getBytes(StandardCharsets.UTF_8));
20 StringBuilder sb = new StringBuilder(out.length * 2);
21 for (byte b : out) {
22 sb.append(String.format("%02x", b & 0xff));
23 }
24 return sb.toString();
25 }
26
27 public static void main(String[] args) throws Exception {
28 String ak = "<AK>";
29 String sk = "<SK>";
30 String host = "keyue.cloud.baidu.com";
31 String timestamp = String.valueOf(Instant.now().toEpochMilli());
32 String nonce = UUID.randomUUID().toString().replace("-", "");
33 String signature = sign(host, ak, sk, timestamp, nonce);
34 System.out.println("Host: " + host);
35 System.out.println("x-ak: " + ak);
36 System.out.println("x-timestamp: " + timestamp);
37 System.out.println("x-nonce: " + nonce);
38 System.out.println("x-signature: " + signature);
39 }
40}
Python 示例
Python
1import hmac
2import hashlib
3import time
4import uuid
5
6def sign(host: str, ak: str, sk: str, timestamp: str, nonce: str) -> str:
7 canonical = (
8 "POST\n"
9 "/open/api/v3/auth/token\n"
10 "\n"
11 f"{host.lower()}\n"
12 f"{ak}\n"
13 f"{timestamp}\n"
14 f"{nonce}\n"
15 "v1"
16 )
17 return hmac.new(sk.encode("utf-8"), canonical.encode("utf-8"), hashlib.sha256).hexdigest()
18
19host = "keyue.cloud.baidu.com"
20ak = "<AK>"
21sk = "<SK>"
22timestamp = str(int(time.time() * 1000))
23nonce = uuid.uuid4().hex
24signature = sign(host, ak, sk, timestamp, nonce)
25print("Host:", host)
26print("x-ak:", ak)
27print("x-timestamp:", timestamp)
28print("x-nonce:", nonce)
29print("x-signature:", signature)
响应参数
| 名称 | 类型 | 必选 | 中文名 | 说明 |
|---|---|---|---|---|
| time | integer | 是 | 时间 | 1717036810964 |
| data | object | 是 | 数据 | 数据对象,详见 data 子数据 |
| code | integer | 是 | 状态码 | 200 |
| msg | string | 是 | 状态信息 | OK |
data 子数据
| 名称 | 类型 | 必选 | 中文名 | 说明 |
|---|---|---|---|---|
| accessToken | string | 是 | 访问令牌,默认以 atk_ 开头 |
|
| tokenType | string | 是 | 固定为 Bearer |
|
| expiresIn | long | 是 | 令牌有效期,单位秒;默认 7200,服务端配置过低时最小返回 60 |
|
| issuedAt | long | 是 | 令牌签发时间,Unix 秒级时间戳 |
请求示例
Bash
1curl --location 'https://keyue.cloud.baidu.com/open/api/v3/auth/token' \
2--header 'x-ak: xxxxxxxx' \
3--header 'x-timestamp: 1772539473423' \
4--header 'x-nonce: 8cdcc8f8f11543d188b2e2155f8ab406' \
5--header 'x-signature: 43626782b57221d6459d3182acdc0eaf1d67e7a0c367c7a7b6a9452dfe8f84ab' \
6--header 'Host: keyue.cloud.baidu.com' \
7--header 'Content-Type: application/json' \
8--data '{
9 "ak":"xxxxxxxx",
10 "sk":"xxxxxxxx"
11}'
响应示例
成功示例
1{
2 "time": 1772539559430,
3 "data": {
4 "accessToken": "atk_w9nQ-bIr78eG7CTloYHcyls41zsEcagtOfgSLLl0r0U",
5 "tokenType": "Bearer",
6 "expiresIn": 7200,
7 "issuedAt": 1772539559
8 },
9 "code": 200,
10 "msg": "OK"
11}
失败响应说明
该接口存在两类失败响应,返回结构略有差异。
1. 签名校验失败
这类错误发生在拦截器阶段,HTTP 状态码通常为 401 或 403,返回体结构如下:
| 名称 | 类型 | 必选 | 说明 |
|---|---|---|---|
code |
integer | 是 | 业务错误码 |
msg |
string | 是 | 错误信息 |
timestamp |
long | 是 | 响应时间,毫秒级时间戳 |
常见错误码:
| 错误码 | 含义 |
|---|---|
4019851 |
AK/SK 鉴权失败,如 AK 格式错误、签名缺失、签名错误、SK 不匹配 |
4019852 |
AccessKey 已禁用 |
4019853 |
时间戳无效或超出 5 分钟窗口 |
4019854 |
请求重复,触发防重放 |
签名失败示例:
JSON
1{
2 "code": 4019853,
3 "msg": "请求时间戳无效或已过期",
4 "timestamp": 1772539559430
5}
2. 请求体凭证校验失败
这类错误发生在控制器/服务层,例如 body 中 ak/sk 非法、未启用、不匹配。默认返回 HTTP 400,返回体结构如下:
| 名称 | 类型 | 必选 | 说明 |
|---|---|---|---|
code |
integer | 是 | 业务错误码 |
msg |
string | 是 | 错误信息 |
tip |
boolean | 否 | 部分异常场景会带出 |
requestId |
string | 否 | 部分场景会带出 |
常见错误码:
| 错误码 | 含义 |
|---|---|
4019851 |
AK/SK 鉴权失败 |
评价此篇文章
