跳到主要内容

介绍

Cloudbase Open API 让开发者可以通过 HTTP 的方式,以管理员身份调用 CloudBase 的服务。

对于 CloudBase 尚未提供 SDK 的语言(如 Java、Go、C++ 等),开发者可以通过此种方式访问 Cloudbase。

了解请求结构

  1. 服务地址

https://tcb-api.tencentcloudapi.com

  1. 请求方法

支持的 HTTP 请求方法:GET, POST, PUT, PATCH, DELETE

  1. 请求头构造
头部字段类型必填说明
X-CloudBase-AuthorizationString结构为:"<凭证版本> <CloudBase 签名>",CloudBase Open API 标准凭证
X-CloudBase-SessionTokenString腾讯云 CAM 临时密钥的 Session Token
X-CloudBase-TimeStampNumberUnix 时间戳,以秒为单位
content-typeStringPOST 时请指定 application/json

使用示例

查询数据库文档

curl -X GET https://tcb-api.tencentcloudapi.com/api/v2/envs/{envId}/databases/{collectionName}/documents/{docId} \
-H "X-CloudBase-Authorization: <authorization>" \
-H "X-CloudBase-TimeStamp: 1551113065" \
-H "X-CloudBase-SessionToken: <sessiontoken>" \

如何获取凭证

1. 从云托管的请求头中获取凭证

云托管的服务中,可以读取请求头中携带的凭证信息,凭证字段 x-cloudbase-authorization,临时密钥字段 x-cloudbase-sessiontoken

以云托管中的 Node.js 服务为例:

const express = require("express");
const got = require("got");
const app = express();

app.get("/", async (req, res) => {
// 从请求头中获取凭证信息
const authorization = req.headers["x-cloudbase-authorization"];
const sessiontoken = req.headers["x-cloudbase-sessiontoken"];
const timestamp = req.headers["x-cloudbase-timestamp"];

// 使用凭证向 CloudBase Open API 发起请求
// 以查询文档为例,先拼接url
const envId = "foo";
const collectionName = "bar";
const docId = "123";
const url = `https://tcb-api.tencentcloudapi.com/api/v2/envs/${envId}/databases/${collectionName}/documents/${docId}`;

// 发起请求,请求头中加入凭证信息
const response = await got(url, {
headers: {
"X-CloudBase-Authorization": authorization,
"X-CloudBase-TimeStamp": timestamp,
"X-CloudBase-SessionToken": sessiontoken,
},
});

res.send(response.body);
});

app.listen(3000);

2. Node.js 服务使用签名工具包计算凭证

Node.js 开发者可以直接使用 Node.js 的签名工具包,无需自行实现签名计算流程:

import { sign } from "@cloudbase/signature-nodejs";

const tmpSecretId = "腾讯云临时密钥SecretId";
const tmpSecretKey = "腾讯云临时密钥SecretKey";
const token = "腾讯云临时密钥Token";

const headers = {
host: "api.tcloudbase.com",
"content-type": "application/json; charset=utf-8",
};

const timestamp = Math.floor(new Date().getTime() / 1000);
const version = "1.0";

const { authorization } = sign({
secretId: tmpSecretId,
secretKey: tmpSecretKey,
method: "POST",
url: "https://api.tcloudbase.com/",
headers,
timestamp,
params: {},
});

// Open API 请求头
const reqHeaders = {};
reqHeaders["X-CloudBase-Authorization"] = version + " " + authorization;
reqHeaders["X-CloudBase-SessionToken"] = token;
reqHeaders["X-CloudBase-TimeStamp"] = timestamp;
提示
  1. 使用永久密钥时,可以忽略 sessionToken 字段,如何获取腾讯云永久密钥,进入腾讯云控制台访问密钥页面查看.
  2. 云函数环境中,可以读取环境变量 process.env.TENCENTCLOUD_SESSIONTOKEN 获取,使用临时密钥时务必设置该头部字段。 :::

3. 使用临时密钥自行计算凭证

对于某些场景,开发者可自行拉取腾讯云临时密钥,计算出凭证,标准流程可以参考 腾讯云 CAM 签名流程

CloudBase 标准凭证与腾讯云 CAM 签名的计算流程大体相同,但在参数上有所简化,以下步骤请配合 腾讯云 CAM 签名流程 阅读。 :::

(1) CanonicalRequest

其中 CanonicalRequest 的各项参数有简化,api.tcloudbase.com 为假设域名,如下:

字段取值
HTTPRequestMethod"POST"
CanonicalURI"//api.tcloudbase.com/"
CanonicalQueryString
CanonicalHeaders"content-type:application/json charset=utf-8\nhost:api.tcloudbase.com\n"
SignedHeaders"content-type;host"
HashedRequestPayload

所以 CanonicalRequest 固定如下:

POST
//api.tcloudbase.com/

content-type:application/json; charset=utf-8
host:api.tcloudbase.com

content-type;host
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

(2) StringToSign

然后计算 StringToSign,假设时间戳为 1600227242,结果如下:

TC3-HMAC-SHA256
1600227242
2020-09-16/tcb/tc3_request
0b986c5cd287577210de28ce0ff9167ada0dbb88736b07ce307b45615a49307e

(3) Signature

我们假设 SecretKey 为 wH72j2a5ZzhwgnXViwVNqdWhWn4AG4iasv26D4JdjBA=,Date 为 2020-09-16,那么 Signature 为:

0ce229810e251baa0ee2bb786c5f9eb6cb7758f55df28cbc161883c48a997e04

(4) 拼接 Authorization

TC3-HMAC-SHA256 Credential=AKIDDo-bNhLNl3kEY5HRzEG-CNUotmyFSadvpKimESWTfND98qyfrpYLCtQJ92_z9yN8/2020-09-16/tcb/tc3_request, SignedHeaders=content-type;host, Signature=0ce229810e251baa0ee2bb786c5f9eb6cb7758f55df28cbc161883c48a997e04

(5) 加上 CloudBase 签名版本

前面加上 1.0 即可:

1.0 TC3-HMAC-SHA256 Credential=AKIDDo-bNhLNl3kEY5HRzEG-CNUotmyFSadvpKimESWTfND98qyfrpYLCtQJ92_z9yN8/2020-09-16/tcb/tc3_request, SignedHeaders=content-type;host, Signature=0ce229810e251baa0ee2bb786c5f9eb6cb7758f55df28cbc161883c48a997e04

JS 凭证示例计算参考

const crypto = require("crypto");
const axios = require("axios");

// 密钥参数
const SECRET_ID = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******";
const SECRET_KEY = "Gu5t9xGARNpq86cd98joQYCN3*******";
const token = ""; //永久密钥则不需要token
const service = "tcb"; //固定值
const timestamp = Math.floor(new Date().getTime() / 1000); //时间戳
const version = "1.0"; //固定值
const date = getDate(timestamp); //时间处理, 获取世界时间日期

// ************* 步骤 1:拼接规范请求串(此处无需操作,都是固定值) *************
const signedHeaders = "content-type;host";
const canonicalRequest = `POST\n//api.tcloudbase.com/\n\ncontent-type:application/json; charset=utf-8\nhost:api.tcloudbase.com\n\ncontent-type;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`;

// ************* 步骤 2:拼接待签名字符串(和示例代码基本无出入) *************
const algorithm = "TC3-HMAC-SHA256";
const hashedCanonicalRequest = getHash(canonicalRequest);
const credentialScope = date + "/" + service + "/" + "tc3_request";
const stringToSign =
algorithm +
"\n" +
timestamp +
"\n" +
credentialScope +
"\n" +
hashedCanonicalRequest;
console.log(stringToSign);

// ************* 步骤 3:计算签名(和示例代码基本无出入) *************
const kDate = sha256(date, "TC3" + SECRET_KEY);
const kService = sha256(service, kDate);
const kSigning = sha256("tc3_request", kService);
const signature = sha256(stringToSign, kSigning, "hex");
console.log(signature);

// ************* 步骤 4:拼接 Authorization(和示例代码基本无出入) *************
const authorization =
algorithm +
" " +
"Credential=" +
SECRET_ID +
"/" +
credentialScope +
", " +
"SignedHeaders=" +
signedHeaders +
", " +
"Signature=" +
signature;
console.log(authorization);

// ************* 步骤 5:拼接 请求头(补充) *************
const reqHeaders = {};
reqHeaders["X-CloudBase-Authorization"] = version + " " + authorization;
reqHeaders["X-CloudBase-SessionToken"] = token;
reqHeaders["X-CloudBase-TimeStamp"] = timestamp;

// ************* 步骤 6:测试访问(请求数据库) *************
axios({
method: "get",
url: "https://tcb-api.tencentcloudapi.com/api/v2/envs/${envid}/databases/${dbname}/documents/${docid}",
headers: reqHeaders,
}).then((res) => res.data);

//以下代码为示例代码中有的

function sha256(message, secret = "", encoding) {
const hmac = crypto.createHmac("sha256", secret);
return hmac.update(message).digest(encoding);
}

function getHash(message, encoding = "hex") {
const hash = crypto.createHash("sha256");
return hash.update(message).digest(encoding);
}

function getDate(timestamp) {
const date = new Date(timestamp * 1000);
const year = date.getUTCFullYear();
const month = ("0" + (date.getUTCMonth() + 1)).slice(-2);
const day = ("0" + date.getUTCDate()).slice(-2);
return `${year}-${month}-${day}`;
}

Python 凭证示例计算参考

# -*- coding: utf-8 -*-
import hashlib, hmac, json, os, sys, time
from datetime import datetime

# 密钥参数
secret_id = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******"
secret_key = "Gu5t9xGARNpq86cd98joQYCN3*******"

service = "tcb"
version = "1.0"
algorithm = "TC3-HMAC-SHA256"
timestamp = int(time.time())
date = datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d")

# ************* 步骤 1:拼接规范请求串 *************
signed_headers = "content-type;host"
canonical_request = "POST\n//api.tcloudbase.com/\n\ncontent-type:application/json; charset=utf-8\nhost:api.tcloudbase.com\n\ncontent-type;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

# ************* 步骤 2:拼接待签名字符串 *************
credential_scope = date + "/" + service + "/" + "tc3_request"
hashed_canonical_request = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
string_to_sign = (algorithm + "\n" +
str(timestamp) + "\n" +
credential_scope + "\n" +
hashed_canonical_request)
print(string_to_sign)


# ************* 步骤 3:计算签名 *************
# 计算签名摘要函数
def sign(key, msg):
return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()
secret_date = sign(("TC3" + secret_key).encode("utf-8"), date)
secret_service = sign(secret_date, service)
secret_signing = sign(secret_service, "tc3_request")
signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
print(signature)

# ************* 步骤 4:拼接 Authorization *************
authorization = (algorithm + " " +
"Credential=" + secret_id + "/" + credential_scope + ", " +
"SignedHeaders=" + signed_headers + ", " +
"Signature=" + signature)
print(authorization)

Java 凭证实例计算参考

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class TencentCloudAPITC3Demo {
private final static Charset UTF8 = StandardCharsets.UTF_8;
private final static String SECRET_ID = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******";
private final static String SECRET_KEY = "Gu5t9xGARNpq86cd98joQYCN3*******";

public static byte[] hmac256(byte[] key, String msg) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
mac.init(secretKeySpec);
return mac.doFinal(msg.getBytes(UTF8));
}

public static String sha256Hex(String s) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] d = md.digest(s.getBytes(UTF8));
return DatatypeConverter.printHexBinary(d).toLowerCase();
}

public static void main(String[] args) throws Exception {
String service = "tcb";//固定值
String version = "1.0";
String algorithm = "TC3-HMAC-SHA256";
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 注意时区,否则容易出错
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));

// ************* 步骤 1:拼接规范请求串(此处无需操作,都是固定值) *************
String signedHeaders = "content-type;host";
String canonicalRequest = `POST\n//api.tcloudbase.com/\n\ncontent-type:application/json; charset=utf-8\nhost:api.tcloudbase.com\n\ncontent-type;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`

// ************* 步骤 2:拼接待签名字符串(和示例代码基本无出入) *************
String credentialScope = date + "/" + service + "/" + "tc3_request";
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
System.out.println(stringToSign);

// ************* 步骤 3:计算签名(和示例代码基本无出入) *************
byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);
byte[] secretService = hmac256(secretDate, service);
byte[] secretSigning = hmac256(secretService, "tc3_request");
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
System.out.println(signature);

// ************* 步骤 4:拼接 Authorization(和示例代码基本无出入) *************
String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
System.out.println(authorization);

// ************* 步骤 5:拼接 请求头(补充) *************
TreeMap<String, String> headers = new TreeMap<String, String>();
headers.put("X-CloudBase-Authorization", version + " " + authorization);
headers.put("X-CloudBase-SessionToken", token);
headers.put("X-CloudBase-TimeStamp", timestamp);

//请使用此headers进行网络请求,访问相关接口
//...相关网络请求代码
}
}