开发须知 #

目前BOOLCMS所有的开放能力皆为内测阶段,暂不开放所有接口,请注意:

  • 调用BOOL服务端接口时,需使用HTTPS协议、JSONFORM数据格式、UTF-8编码。
  • 在调用API前,确保您已了解调用频率限制为30QPS/s
  • query指该参数需在请求URL传参
  • body指该参数需在请求JSON传参

基础概念 #

ISV 身份 #

授权对象ISV即服务商、应用开发者。

APP 身份 #

授权对象APP即开放应用,由服务商进行管理、开发的应用。

ApiKey/ApiSecret #

ApiKey是服务商ISV调用API的唯一身份标识,ApiSecret是对应的API密钥。

AppId/AppSecret #

AppId是开放应用APP的唯一身份标识,AppSecret是对应的应用的密钥。

HTTP Headers #

HTTP Header 描述
Authorization 用于验证请求合法性的认证信息。请严格按照签名格式进行填充,否则会返回401 HTTP状态码。
Content-Type 请求或响应内容的 MIME 类型。例如Content-Type: application/json;charset=UTF-8application/x-www-form-urlencoded
User-Agent 每次请求中此HTTP Header会标识自己,若没有此信息将会拒绝请求。
X-APPID ApiKey或者AppId
X-Source ISV或者APP
X-Expiration 请求时间,请使用Unix时间戳。
X-Host 服务器域名。例如X-Host: https://api.boolc.cn

响应格式 #

通过API请求,响应头部信息包括:

  • 2xx3xx4xx5xx的HTTP状态码
  • Content-Type: application/json;charset=UTF-8

数据格式 #

HTTP状态码为2xx,接口状态码为2xxxx,API执行后将返回一个JSON格式的信息对象。具体格式如下:

{
	"code": <Code int>,
	"data": <Data interface{}>,
    "msg": "<Msg string>"
}
Key 描述
code 接口状态码,该状态码不同于HTTP状态码,是接口定义的状态码。
data 接口返回的数据,详见对应接口的响应数据。
msg 正确/错误返回信息提示。

接口状态码 #

状态码 描述
20000 接口请求成功。
40001 参数方面的异常状态,如参数格式错误、参数长度错误等。
40003 鉴权失败,若在网关鉴权错误HTTP状态码为2xx,若在服务内部鉴权错误HTTP状态码为401
40005 系统维护、更新等状态产生的问题。
40008 未经授权的系统,和40003区别在于系统鉴权问题,将会记录黑名单。
50000 系统错误,请将请求头、参数、签名等信息截图交由技术协调处理。
50001 未知错误,请将请求头、参数、签名等信息截图交由技术协调处理。
50008 Token非法、失效等情况返回的状态码。

签名 #

API通过验证签名来保证请求的真实性和数据的完整性。

请求签名 #

请使用ApiKey/ApiSecretAppId/AppSecret对API HOST、Body等关键数据的组合进行HmacSHA256签名。请求签名通过HTTP Header Authorization传递,具体说明请见下方说明。没有携带签名或者签名验证不通过的请求,都不会被执行,并返回401 Unauthorized。

1 签名字符串 #

X-APPIDX-ExpirationX-HostX-Source填充后,将四个HTTP Headers(Key通过ASCII排序)以及Body用&进行拼接,即:

<HTTP Headers Key string>=<HTTP Headers Value string>&<Body string>

例如:

X-APPID=GV5CD2hnRfRv47Ju&X-Expiration=1625481243&X-Host=https://api.boolc.cn&X-Source=ISV&{"channel":"BOOL"}

2 签名密钥 #

ApiSecretAppSecretX-Expiration拼接

<ApiSecret/AppSecret string><X-Expiration string>

3 加签 #

将上方两步生成的签名字符串、签名密钥,使用HmacSHA256算法计算签名,然后进行Base64 encode,得到最终的签名(需要使用UTF-8字符集),将计算的签名放入Headers的Authorization中。

签名计算示例代码 Go #

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"
)

func sign() error {
	expiration := strconv.Itoa(int(time.Now().Unix()))
	params := map[string]string{
		"channel": "BOOL",
	}
	body, err := json.Marshal(params)
	if err != nil {
		return err
	}

	conn, err := http.NewRequest("POST", "<BoolApiURL string>", strings.NewReader(string(body)))
	if err != nil {
		return err
	}
	client := &http.Client{}
	// 设置请求头
	conn.Header.Set("X-APPID", <ApiKey string>)
	conn.Header.Set("X-Expiration", expiration)
	conn.Header.Set("X-Host", <ApiHost string>)
	conn.Header.Set("X-Source", <Source string>)

    // 拼接签名密钥
	secret := "<ApiSecret string>" + expiration

	var keys []string
	for k := range conn.Header {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var pList = make([]string, 0, 0)
	for _, key := range keys {
		pList = append(pList, key+"="+conn.Header.Get(key))
	}
	pList = append(pList, string(body))
	// 生成签名字符串
	var content = strings.Join(pList, "&")

    // 加签并发送请求
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(content))
	sha := hex.EncodeToString(h.Sum(nil))
	
	conn.Header.Set("Content-Type", "application/json")
	conn.Header.Set("Authorization", base64.StdEncoding.EncodeToString([]byte(sha)))

	resp, err := client.Do(conn)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	return nil
}

签名计算代码示例 Python #

#python 3.8
import time
import hmac
import hashlib
import base64
import httplib
import urllib

expiration = str(time.time())
params = '{"channel": "BOOL"}'
headers = { "X-APPID": "ApiKey", "X-Expiration": expiration, "X-Host": "API HOST", "X-Source": "Source" }

secret = "ApiSecret"+expiration
secret_enc = secret.encode('utf-8')

string_to_sign = ""
for key in sorted(headers):
    string_to_sign += "{}={}&".format(key, headers[key])

string_to_sign += params
string_to_sign_enc = string_to_sign.encode("utf-8")

# 加签并发送请求
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code)

headers["Content-Type"] = "application/json"
headers["Authorization"] = sign
conn = httplib.HTTPConnection("BOOL API URL")
conn.request("POST", "/", params, headers)

response = conn.getresponse()
data = response.read()
conn.close()
上次更新: 8/8/2022, 8:59:39 PM