文章目录
- [海康 Artemis 接口调试:用 Postman + AK/SK 快速跑通接口](#海康 Artemis 接口调试:用 Postman + AK/SK 快速跑通接口)
- [二、AK、SK、Signature 是什么](#二、AK、SK、Signature 是什么)
- [三、Postman 需要配置什么](#三、Postman 需要配置什么)
-
- [1. Environment](#1. Environment)
- [2. Request](#2. Request)
- [3. Before Request Script](#3. Before Request Script)
- [四、Signature 是怎么生成的](#四、Signature 是怎么生成的)
-
- [1. 生成 nonce](#1. 生成 nonce)
- [2. 生成 timestamp](#2. 生成 timestamp)
- [3. 获取当前 Path](#3. 获取当前 Path)
- [五、构造 StringToSign](#五、构造 StringToSign)
- [六、计算 Signature](#六、计算 Signature)
- [七、Postman 通用签名脚本](#七、Postman 通用签名脚本)
- 八、以后拿到一个新接口怎么调
-
- [第一步:复制已经跑通的 Request](#第一步:复制已经跑通的 Request)
- [第二步:修改 Method 和 URL](#第二步:修改 Method 和 URL)
- 第三步:修改请求参数
- [第四步:选择 Environment](#第四步:选择 Environment)
- [第五步:点击 Send](#第五步:点击 Send)
- 九、接口失败时怎么快速排查
- [十、为什么 HTTP 200 不一定代表接口成功](#十、为什么 HTTP 200 不一定代表接口成功)
- 十一、常见问题总结
-
- [1. Signature invalid](#1. Signature invalid)
- [2. AK 正确,但还是鉴权失败](#2. AK 正确,但还是鉴权失败)
- [3. 为什么 SK 不放在 Header](#3. 为什么 SK 不放在 Header)
- [4. 为什么每次 Signature 都不一样](#4. 为什么每次 Signature 都不一样)
海康 Artemis 接口调试:用 Postman + AK/SK 快速跑通接口
一、这篇文章要解决什么问题
在对接海康 Artemis 接口时,我们通常会拿到这些信息:
text
接口地址
Method
请求参数
AK
SK
但如果只是把 URL 和 Body 直接填进 Postman,接口通常并不能直接调用成功。
原因是 Artemis 在真正访问业务接口之前,还需要完成一层:
text
AK/SK 签名鉴权
也就是说,请求并不是简单地:
text
URL + Body → Send
而是需要先根据当前请求动态生成:
text
nonce
timestamp
Signature
再把这些鉴权信息一起发送给 Artemis。
这篇文章的目的,就是沉淀一套可以长期复用的 Postman 调试模板。
以后再拿到一个新的 Artemis 接口,只需要准备:
text
Method
接口 Path
Params / Body
AK
SK
然后复用已经配置好的 Postman 签名脚本,就可以开始调试,而不需要每次重新研究 AK/SK 签名逻辑。
注意:本文中的域名、IP、AK、SK、接口 Path 和请求数据均为脱敏或模拟内容,不对应任何真实生产环境。
二、AK、SK、Signature 是什么
可以先简单理解成:
text
AK = 应用身份
SK = 签名密钥
Signature = 使用 SK 计算出来的一次性签名
其中:
AK 会随请求发送给 Artemis。
SK 不会直接发送给服务器。
SK 只用于在本地计算 Signature。
整个过程可以理解为:
text
客户端拥有 AK + SK
↓
读取当前请求信息
↓
生成 nonce + timestamp
↓
拼接 StringToSign
↓
使用 SK 计算 Signature
↓
请求携带
AK + nonce + timestamp + Signature
↓
发送给 Artemis
↓
Artemis 验证 Signature
↓
通过后访问业务接口
服务器收到请求后,会根据对应规则重新计算签名。
如果:
text
客户端 Signature
=
服务端计算结果
则签名校验通过。
因此需要特别注意:
SK 不要直接放进 Header,也不要出现在公开文章、截图、代码仓库或日志中。
三、Postman 需要配置什么
整个 Postman 模板主要包括三个部分:
text
Environment
+
Request
+
Before Request Script
1. Environment
建议创建一个 Environment,例如:
text
HIK-Artemis
配置三个变量:
| Variable | 作用 |
|---|---|
HIK_HOST |
Artemis 网关地址 |
AK |
应用身份 |
SK |
签名密钥 |
例如:
text
HIK_HOST = https://example.com
AK = ********
SK = ********
以后接口地址统一写成:
text
{{HIK_HOST}}/artemis/api/example/v1/resource/search
这样服务器地址、AK、SK 都不需要直接写死在 Request 中。
2. Request
Request 只需要关注业务接口本身。
例如:
text
POST
{{HIK_HOST}}/artemis/api/example/v1/resource/search
Body:
json
{
"pageNo": 1,
"pageSize": 20
}
以后换新接口时,通常只需要修改:
text
Method
URL
Params / Body
鉴权代码不需要跟着业务接口一起修改。
3. Before Request Script
Before Request Script 会在真正发送请求之前自动执行。
它主要负责:
text
读取 AK / SK
↓
生成 nonce
↓
生成 timestamp
↓
获取 Method 和 Path
↓
构造 StringToSign
↓
计算 Signature
↓
写入 Header
↓
发送请求
也就是说,点击 Send 后,签名过程可以自动完成。
四、Signature 是怎么生成的
签名看起来复杂,但核心步骤并不多。
1. 生成 nonce
nonce 可以理解为本次请求的随机标识。
通常可以生成一个 UUID,例如:
text
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
每次请求重新生成。
2. 生成 timestamp
使用当前的毫秒级 Unix 时间戳:
javascript
Date.now()
Java 中对应:
java
System.currentTimeMillis()
例如:
text
1700000000000
这里要注意:
text
使用毫秒时间戳
而不是秒级时间戳。
3. 获取当前 Path
例如请求地址:
text
https://example.com/artemis/api/example/v1/resource/search
参与签名的 Path 为:
text
/artemis/api/example/v1/resource/search
在 Postman 中建议直接获取:
javascript
pm.request.url.getPath()
尽量不要手工写死 Path。
因为:
text
/api/example/v1/resource/search
和:
text
/artemis/api/example/v1/resource/search
对于签名算法来说,是两个完全不同的字符串。
只要参与签名的 Path 和实际请求 Path 不一致,就可能出现:
text
Signature invalid
五、构造 StringToSign
通常需要按照固定顺序,把参与签名的内容拼接起来,例如:
text
Method
Accept
Content-Type
x-ca-key
x-ca-nonce
x-ca-timestamp
Path
示意如下:
text
POST
*/*
application/json
x-ca-key:********
x-ca-nonce:xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
x-ca-timestamp:1700000000000
/artemis/api/example/v1/resource/search
字段之间使用:
text
\n
连接。
JavaScript 示例:
javascript
const stringToSign = [
method,
accept,
contentType,
`x-ca-key:${AK}`,
`x-ca-nonce:${nonce}`,
`x-ca-timestamp:${timestamp}`,
path
].join('\n');
需要注意:
text
字段顺序
换行符
Header 名称
Path
只要有一项和服务端要求不一致,都可能导致签名校验失败。
六、计算 Signature
签名计算通常可以理解为:
text
Signature
=
Base64(
HMAC-SHA256(
StringToSign,
SK
)
)
其中:
text
StringToSign = 待签名字符串
SK = 密钥
HMAC-SHA256 = 签名算法
Base64 = 最终编码方式
Postman 中可以通过 CryptoJS 完成:
javascript
const signature = CryptoJS.HmacSHA256(
stringToSign,
CryptoJS.enc.Utf8.parse(SK)
).toString(CryptoJS.enc.Base64);
最终得到的 Signature 会写入:
text
x-ca-signature
七、Postman 通用签名脚本
下面这段代码可以作为 Artemis 接口调试模板。
放在:
text
Scripts
→ Before request
中。
javascript
const CryptoJS = require('crypto-js');
// 读取 AK / SK
const AK = pm.environment.get('AK');
const SK = pm.environment.get('SK');
if (!AK || !SK) {
throw new Error('AK 或 SK 未配置');
}
// 获取请求 Method
const method = pm.request.method.toUpperCase();
// 获取 Path
let path = pm.request.url.getPath();
if (!path) {
const rawUrl = pm.request.url.toString();
path = rawUrl
.replace(/^https?:\/\/[^\/]+/i, '')
.split('?')[0];
}
const accept = '*/*';
const contentType = 'application/json';
// 生成 nonce
function newGuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x'
? r
: (r & 0x3 | 0x8);
return v.toString(16);
});
}
const nonce = newGuid();
// 毫秒级时间戳
const timestamp = Date.now().toString();
// 构造 StringToSign
const stringToSign = [
method,
accept,
contentType,
`x-ca-key:${AK}`,
`x-ca-nonce:${nonce}`,
`x-ca-timestamp:${timestamp}`,
path
].join('\n');
// 计算 Signature
const signature = CryptoJS.HmacSHA256(
stringToSign,
CryptoJS.enc.Utf8.parse(SK)
).toString(CryptoJS.enc.Base64);
// 写入 Header
pm.request.headers.upsert({
key: 'Accept',
value: accept
});
pm.request.headers.upsert({
key: 'Content-Type',
value: contentType
});
pm.request.headers.upsert({
key: 'x-ca-key',
value: AK
});
pm.request.headers.upsert({
key: 'x-ca-nonce',
value: nonce
});
pm.request.headers.upsert({
key: 'x-ca-timestamp',
value: timestamp
});
pm.request.headers.upsert({
key: 'x-ca-signature',
value: signature
});
pm.request.headers.upsert({
key: 'x-ca-signature-headers',
value: 'x-ca-key,x-ca-nonce,x-ca-timestamp'
});
配置完成以后,正常情况下 Signature 不需要手工计算。
八、以后拿到一个新接口怎么调
以后再拿到新的 Artemis API,可以固定按照下面几步操作。
第一步:复制已经跑通的 Request
不要每次都从空白 Request 开始。
直接复制之前已经成功调用的 Artemis Request。
这样可以保留:
text
Environment
Header
Before Request Script
鉴权配置
第二步:修改 Method 和 URL
例如:
text
POST
{{HIK_HOST}}/artemis/api/example/v1/resource/search
根据接口文档修改成对应的 Method 和 Path。
第三步:修改请求参数
根据接口文档填写:
text
Params
或者:
text
Body
例如:
json
{
"pageNo": 1,
"pageSize": 20
}
第四步:选择 Environment
确认当前 Environment 为:
text
HIK-Artemis
并且已经正确配置:
text
HIK_HOST
AK
SK
第五步:点击 Send
点击 Send 后,签名脚本会自动执行:
text
nonce
↓
timestamp
↓
Path
↓
StringToSign
↓
HMAC-SHA256
↓
Base64
↓
Signature
↓
Header
↓
发送请求
因此以后调新的 Artemis API,真正需要关注的主要是:
text
Method
URL
Params / Body
九、接口失败时怎么快速排查
不要看到报错以后就随机修改参数。
建议按照网络、鉴权、业务参数三个层级逐步排查。
| 返回现象 | 优先排查 |
|---|---|
| Connection timeout | IP、端口、VPN、网络 |
| SSL Error | HTTPS、证书 |
| AppKey is null | x-ca-key |
| Signature is null | Before Request Script 是否执行 |
| Signature invalid | SK、Path、字段顺序、换行符 |
| 参数校验错误 | Params / Body |
| HTTP 200 但业务失败 | Response Body 中的业务状态 |
| 返回正常业务数据 | 接口基本调用成功 |
推荐排查顺序:
text
网络通不通?
↓
HTTPS 是否正确?
↓
AK 有没有传?
↓
Signature 有没有生成?
↓
SK 是否正确?
↓
参与签名的 Path 是否正确?
↓
签名字段顺序是否一致?
↓
Body / Params 是否正确?
十、为什么 HTTP 200 不一定代表接口成功
接口调试时有一个很容易误判的问题:
text
HTTP 200
并不一定代表:
text
业务调用成功
HTTP 200 只能说明:
text
HTTP 请求已经正常到达服务器,
并且服务器正常返回了 HTTP 响应。
但 Response Body 中仍然可能返回业务错误,例如:
json
{
"code": "ERROR_CODE",
"msg": "Signature invalid"
}
这种情况下,网络层是通的,但鉴权仍然失败。
因此判断一个接口是否真正跑通,建议同时看:
text
HTTP Status
+
Response code
+
Response message
+
业务数据
而不要只看:
text
HTTP 200
十一、常见问题总结
1. Signature invalid
优先检查:
text
SK 是否正确
Path 是否正确
Method 是否正确
换行符是否正确
Header 顺序是否正确
timestamp 是否符合要求
其中 Path 是非常常见的问题。
2. AK 正确,但还是鉴权失败
AK 只是用来标识应用。
真正决定签名是否正确的是:
text
AK
+
SK
+
StringToSign
因此:
text
AK 正确
并不代表:
text
Signature 一定正确
3. 为什么 SK 不放在 Header
因为 SK 本质上属于:
text
Secret Key
作用是证明:
text
客户端确实拥有这个秘密
正确方式应该是:
text
SK
↓
本地计算 Signature
↓
只发送 Signature
而不是:
text
直接发送 SK
4. 为什么每次 Signature 都不一样
因为参与签名的信息中通常包含:
text
nonce
timestamp
每次请求:
text
nonce 不同
timestamp 不同
所以:
text
StringToSign 不同
最终:
text
Signature 也不同
这是正常现象。