# 签名机制
API 网关会对每个访问的请求进行身份验证,所以无论使用 HTTP 还是 HTTPS 协议提交请求,都需要在请求中包含签名(api_sign)信息。
AppNode 使用 SignKey 签名密钥对请求 URL 进行签名加密以验证请求的有效性,请勿泄露签名密钥。
## 获取签名密钥
### 在面板上获取签名密钥
请参考:[获取 API 网关地址](agent/publish-agent-api.md)
### 通过命令行获取签名密钥
使用 `appnode agent config agent_sign_key` 命令即可获得受控端的 API 签名密钥:
```bash
# appnode agent config agent_sign_key
agent_sign_key : 95bAzsK4AuYbrEnFjfUGdku5CXz2yKJn
```
## 签名操作
在进行 API 请求时,需要按照以下方法对请求进行签名处理:
1. 对请求参数进行排序,排序规则:
* 按参数名的字典顺序排序
* 如果有多个相同参数名的参数,则按参数值的字典顺序排序
2. 按以下方式连接排序后的参数名和参数值,得到待签名字符串:
`URLENCODE(参数名1)=URLENCODE(参数值1)&URLENCODE(参数名2)=URLENCODE(参数值2)&...`
即先使用 `URLENCODE()` 对参数名和参数值进行 URL 编码,然后用 `&` 符号连接起来。
3. 对第2步得到的待签名字符串,计算出 HMAC-MD5 值,以字符串形式输出,即为签名值。使用 HMAC-MD5 算法计算签名时使用的 Key 就是 API 签名密钥;
4. 将得到的签名值,作为 api_sign 参数添加到请求参数中,即完成对请求签名的过程。
### 示例
以系统信息应用的 `Status.Overview` 接口为例,假设受控端使用的 API 接口密钥为 `95bAzsK4AuYbrEnFjfUGdku5CXz2yKJn`。 那么签名前的请求 URL 为:
```raw
http://192.168.1.128/?api_action=Status.Overview&api_agent_app=sysinfo&api_format=json
&api_lang=zh_cn&api_timestamp=1515502060&api_nonce=8YyjYz9t6H3ZVraY
```
计算得到的待签名字符串为:
```raw
api_action=Status.Overview&api_agent_app=sysinfo&api_format=json&api_lang=zh_cn&api_nonce=8YyjYz9t6H3ZVraY&api_timestamp=1515502060
```
使用签名密钥 `95bAzsK4AuYbrEnFjfUGdku5CXz2yKJn` 计算 HMAC-MD5,计算得到的签名值为:
`08ce8db013695057ef53b04e61ba3c76`
将签名作为 `api_sign` 参数加入到 URL 请求中,最后得到的 URL 为:
```raw
http://192.168.1.128/?api_action=Status.Overview&api_agent_app=sysinfo&api_format=json
&api_lang=zh_cn&api_timestamp=1515502060&api_nonce=8YyjYz9t6H3ZVraY&api_sign=08ce8db013695057ef53b04e61ba3c76
```