海康 Artemis 接口对接

文章目录

  • [海康 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 也不同

这是正常现象。



相关推荐
2601_962218611 小时前
C++中decltype关键字的实现
开发语言·c++
hqyjzsb1 小时前
法律 Prompt 干货:搭建合同审查提示词要包含哪些要素
开发语言·人工智能·python·职场和发展·数据分析·prompt·业界资讯
孙启超1 小时前
【AI开发之Rust】第 19 课:UniFFI 导出核心能力
开发语言·后端·rust
2601_966949652 小时前
股票池发生变化后,如何高效更新行情数据?从全量刷新到增量同步
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
繁华的地方不一定留下你的脚印2 小时前
C++ std::variant 与 std::visit:安全保存多种类型,写清每个处理分支
开发语言·c++
小羊没烦恼!2 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
❀͜͡傀儡师2 小时前
20 年沉淀,CAS 8.0 重新定义企业级 SSO:适配 JDK 25 与 Spring Boot 4.1
java·开发语言·spring boot
weixin_307779132 小时前
基于睿擎工业开发平台的预训练视觉模型轻量化适配与低代码部署优化
开发语言·算法
实心儿儿2 小时前
Qt — Qt 多线程
开发语言·qt