🏪 蓉易推 · 客户端对接指南

版本分发系统 · Agent API 接入文档

📖 概述

蓉易推平台管理端为客户系统提供版本管理、授权验证、自动更新等 API 服务。

客户系统(Agent)通过 HTTPS 调用以下 API 端点,所有请求需要携带授权信息进行签名验证。

API 地址 https://xxx.com/api/agent/

授权校验 所有 Agent API 通过 x-license-key + x-signature + x-timestamp 三个 Header 进行身份验证

🚀 快速接入
  1. 获取授权密钥

    联系蓉易推管理员开通客户账号,管理员会提供给你一个 license_key(格式:XXXXXX-XXXXXX-XXXXXX-XXXXXX)和对应的 client_id

  2. 生成签名

    每次请求前,按以下规则计算签名:

    signStr = license_key + ":" + timestamp + ":" + client_id
    signature = SHA256(signStr)
    
    // timestamp 为当前毫秒时间戳(13位)
    // 请求时间戳与服务器时间不得超过 5 分钟差异
  3. 设置 HTTP 请求头
    x-license-key: <你的授权密钥>
    x-signature: <上一步计算的签名>
    x-timestamp: <当前毫秒时间戳>
  4. 调用 API

    带上上述 Header,请求任一 Agent API 接口。成功返回 {"success": true, "data": {...}},失败返回 {"success": false, "msg": "..."}

📡 API 接口文档

1. 验证授权 POST

验证 license_key 是否有效、是否在有效期内。

接口/api/agent/verify
请求体

返回示例

{
  "success": true,
  "data": {
    "valid": true,
    "client_id": 1,
    "client_name": "成都xxx科技",
    "license_type": "year",
    "license_expire": "2027-07-18"
  }
}

2. 检查更新 POST

传入当前版本号,返回是否有新版本、更新日志、是否强制更新等信息。

接口/api/agent/check
请求体{"current_version": "1.0.0"}

返回示例

{
  "success": true,
  "data": {
    "hasUpdate": true,
    "current_version": "1.0.0",
    "latest_version": "1.1.0",
    "title": "性能优化与BUG修复",
    "changelog": "1. 修复xxx问题\n2. 优化xxx",
    "is_required": true,
    "package_file": "v1.1.0.zip",
    "package_size": 1048576,
    "package_checksum": "a1b2c3d4..."
  }
}

3. 下载更新包 POST

根据版本号下载更新包(Base64 编码)。

接口/api/agent/download
请求体{"version": "1.1.0"}

返回示例

{
  "success": true,
  "data": {
    "filename": "v1.1.0.zip",
    "size": 1048576,
    "checksum": "a1b2c3d4...",
    "file_data": "UEsDBBQAAAAIA..."  // Base64 编码的文件内容
  }
}

4. 上报更新结果 POST

更新完成后上报结果到平台,用于记录更新日志和更新客户端当前版本。

接口/api/agent/report
请求体{"from_version": "1.0.0", "to_version": "1.1.0", "status": "success", "error_msg": ""}

5. 心跳上报 POST

定期上报运行状态(建议每 5-10 分钟调用一次)。

接口/api/agent/heartbeat
请求体{"current_version": "1.1.0", "status": "online", "system_info": {"os":"linux","cpu":4,"mem":8192}}
💻 代码示例

JavaScript (Node.js)

const crypto = require('crypto');

const LICENSE_KEY = 'XXXXXX-XXXXXX-XXXXXX-XXXXXX';
const CLIENT_ID = 1;
const BASE_URL = 'https://xxx.com';

function generateSignature() {
  const timestamp = Date.now().toString();
  const signStr = `${LICENSE_KEY}:${timestamp}:${CLIENT_ID}`;
  const signature = crypto.createHash('sha256').update(signStr).digest('hex');
  return { timestamp, signature, signStr };
}

async function agentAPI(endpoint, body = {}) {
  const { timestamp, signature } = generateSignature();
  const res = await fetch(`${BASE_URL}/api/agent/${endpoint}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-license-key': LICENSE_KEY,
      'x-signature': signature,
      'x-timestamp': timestamp
    },
    body: JSON.stringify(body)
  });
  return res.json();
}

// 验证授权
const verifyResult = await agentAPI('verify');

// 检查更新
const checkResult = await agentAPI('check', { current_version: '1.0.0' });

// 下载更新包
if (checkResult.data.hasUpdate) {
  const dl = await agentAPI('download', { version: '1.1.0' });
  // dl.data.file_data 是 Base64 编码的文件内容
  // 验证 dl.data.checksum 后写入本地
}

Python

import hashlib
import time
import requests

LICENSE_KEY = 'XXXXXX-XXXXXX-XXXXXX-XXXXXX'
CLIENT_ID = 1
BASE_URL = 'https://xxx.com'

def generate_signature():
    timestamp = str(int(time.time() * 1000))
    sign_str = f"{LICENSE_KEY}:{timestamp}:{CLIENT_ID}"
    signature = hashlib.sha256(sign_str.encode()).hexdigest()
    return timestamp, signature

def call_api(endpoint, data=None):
    timestamp, signature = generate_signature()
    headers = {
        'Content-Type': 'application/json',
        'x-license-key': LICENSE_KEY,
        'x-signature': signature,
        'x-timestamp': timestamp
    }
    r = requests.post(f"{BASE_URL}/api/agent/{endpoint}", json=data, headers=headers)
    return r.json()

# 检查更新
result = call_api('check', {'current_version': '1.0.0'})
if result['success'] and result['data']['hasUpdate']:
    print(f"有新版本: {result['data']['latest_version']}")
    print(f"更新日志: {result['data']['changelog']}")
    # 下载更新包
    dl = call_api('download', {'version': result['data']['latest_version']})

Shell (curl)

# 先用 JavaScript/Python 生成签名,然后执行:
curl -X POST https://xxx.com/api/agent/check \
  -H "Content-Type: application/json" \
  -H "x-license-key: XXXXXX-XXXXXX-XXXXXX-XXXXXX" \
  -H "x-signature: <计算出的签名>" \
  -H "x-timestamp: <当前毫秒时间戳>" \
  -d '{"current_version": "1.0.0"}'
⚠️ 常见错误
HTTP 状态码错误消息说明
401缺少授权信息请求头缺少 x-license-keyx-signaturex-timestamp
401请求已过期请求时间戳与服务器时间差超过 5 分钟,检查系统时间同步
403授权无效或已停用license_key 不存在或该客户已被停用
403签名验证失败计算签名时用的参数不匹配,检查 key:timestamp:client_id 是否正确
💡 签名调试小技巧:
签名公式为 SHA256(license_key + ":" + timestamp + ":" + client_id)
其中 timestamp13 位毫秒时间戳client_id 可通过调用 /api/agent/verify 用正确的密钥获取(如果还不知道 client_id,可以先用 curl 带正确签名测试返回的 client_id)。
🔄 推荐集成流程

启动时:

1. 调用 /api/agent/verify 验证授权是否有效
2. 调用 /api/agent/check 检查是否有新版本

有更新时:

3. 调用 /api/agent/download 下载更新包
4. 解压/替换文件
5. 调用 /api/agent/report 上报更新结果(成功或失败)

运行期间:

6. 每 5-10 分钟调用 /api/agent/heartbeat 上报心跳