Skip to main content

Introduction

Cloudbase Open API enables developers to invoke CloudBase services as administrators via HTTP.

For languages for which CloudBase does not provide an SDK (such as Java, Go, C++, etc.), developers can access Cloudbase in this way.

Understanding the Request Structure

  1. Service Address

https://tcb-api.tencentcloudapi.com

  1. Request Method

Supported HTTP request methods: GET, POST, PUT, PATCH, DELETE

  1. Request Header Construction
Header FieldTypeRequiredDescription
X-CloudBase-AuthorizationStringRequiredStructure: "<Credential Version> <CloudBase Signature>", CloudBase Open API standard credential
X-CloudBase-SessionTokenStringRequiredSession Token for Tencent Cloud CAM temporary key
X-CloudBase-TimeStampNumberNoUnix timestamp in seconds
content-typeStringNoSpecify application/json for POST requests

Usage Example

Query database documents

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>" \

How to Obtain Credentials

1. Obtain Credentials from Cloud Hosting Request Headers

In Cloud Hosting services, credential information can be obtained from the request headers, with the credential field x-cloudbase-authorization and the temporary key field x-cloudbase-sessiontoken.

Take the Node.js service in Cloud Hosting as an example:

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

app.get("/", async (req, res) => {
// Obtain credential information from request headers
const authorization = req.headers["x-cloudbase-authorization"];
const sessiontoken = req.headers["x-cloudbase-sessiontoken"];
const timestamp = req.headers["x-cloudbase-timestamp"];

// Use credentials to make a request to CloudBase Open API
// Take querying documents as an example, first construct the 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}`;

// Send the request with credentials added to the headers
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 service computes credentials using the signature toolkit

Node.js developers can directly use the Node.js signature toolkit without implementing the signature calculation process themselves:

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

const tmpSecretId = "Tencent Cloud temporary key SecretId";
const tmpSecretKey = "Tencent Cloud temporary key SecretKey";
const token = "Tencent Cloud temporary key 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 request header
const reqHeaders = {};
reqHeaders["X-CloudBase-Authorization"] = version + " " + authorization;
reqHeaders["X-CloudBase-SessionToken"] = token;
reqHeaders["X-CloudBase-TimeStamp"] = timestamp;
tip
  1. When using a permanent key, you can ignore the sessionToken field. To obtain a Tencent Cloud permanent key, visit the Access Key page in the Tencent Cloud console.
  2. In the cloud function environment, it can be obtained by reading the environment variable process.env.TENCENTCLOUD_SESSIONTOKEN. When using temporary keys, be sure to set this header field. :::

3. Compute credentials by yourself using a temporary key

For certain scenarios, developers can retrieve Tencent Cloud temporary keys by themselves and compute credentials. The standard process can be referred to in the Tencent Cloud CAM signature process.

The CloudBase standard credential computation process is largely the same as the Tencent Cloud CAM signature process, but simplified in parameters. Please read the following steps in conjunction with the Tencent Cloud CAM signature process. :::

(1) CanonicalRequest

Among them, the parameters of CanonicalRequest are simplified, and api.tcloudbase.com is a hypothetical domain, as follows:

FieldValue
HTTPRequestMethod"POST"
CanonicalURI"//api.tcloudbase.com/"
CanonicalQueryStringempty
CanonicalHeaders"content-type:application/json charset=utf-8\nhost:api.tcloudbase.com\n"
SignedHeaders"content-type;host"
HashedRequestPayloadempty

Therefore, CanonicalRequest is fixed as follows:

POST
//api.tcloudbase.com/

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

content-type;host
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

(2) StringToSign

Then compute StringToSign, assuming the timestamp is 1600227242, as follows:

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

(3) Signature

Assume the SecretKey is wH72j2a5ZzhwgnXViwVNqdWhWn4AG4iasv26D4JdjBA=, and the Date is 2020-09-16, then the Signature is:

0ce229810e251baa0ee2bb786c5f9eb6cb7758f55df28cbc161883c48a997e04

(4) Concatenate Authorization

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

(5) Add the CloudBase signature version

Prepend 1.0 to get:

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

Example Calculation for JS Credentials

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

// Key parameters
const SECRET_ID = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3*******";
const SECRET_KEY = "Gu5t9xGARNpq86cd98joQYCN3*******";
const token = ""; //For permanent keys, the token is not required
const service = "tcb"; //Fixed value
const timestamp = Math.floor(new Date().getTime() / 1000); // Timestamp
const version = "1.0"; // Fixed value
const date = getDate(timestamp); // Time processing to obtain UTC date

// ************* Step 1: Concatenate the canonical request string (no action required here as all are fixed values) *************
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`;

// ************* Step 2: Concatenate the string to be signed (essentially identical to the sample code) *************
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);

// ************* Step 3: Calculate the signature (essentially identical to the sample code) *************
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);

// ************* Step 4: Concatenate Authorization (essentially identical to the sample code) *************
const authorization =
algorithm +
" " +
"Credential=" +
SECRET_ID +
"/" +
credentialScope +
", " +
"SignedHeaders=" +
signedHeaders +
", " +
"Signature=" +
signature;
console.log(authorization);

// ************* Step 5: Concatenate request headers (supplementary) *************
const reqHeaders = {};
reqHeaders["X-CloudBase-Authorization"] = version + " " + authorization;
reqHeaders["X-CloudBase-SessionToken"] = token;
reqHeaders["X-CloudBase-TimeStamp"] = timestamp;

// ************* Step 6: Test access (request database) *************
axios({
method: "get",
url: "https://tcb-api.tencentcloudapi.com/api/v2/envs/${envid}/databases/${dbname}/documents/${docid}",
headers: reqHeaders,
}).then((res) => res.data);

// The following code is present in the sample code

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 Credentials Sample Calculation Reference

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

# Key parameters
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")

# ************* Step 1: Concatenate specification request strings *************
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"

# ************* Step 2: Concatenate strings to be signed *************
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)


# ************* Step 3 Calculate the signature *************
# Calculate signature digest function
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)

#************Step 4: Concatenate Authorization *************
authorization = (algorithm + " " +
"Credential=" + secret_id + "/" + credential_scope + ", " +
"SignedHeaders=" + signed_headers + ", " +
"Signature=" + signature)
print(authorization)

Java Credential Instance Calculation Reference

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";//Fixed value
String version = "1.0";
String algorithm = "TC3-HMAC-SHA256";
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// Note the time zone, otherwise errors may occur
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));

// ************* Step 1: Concatenate the canonical request string (no action required here as all are fixed values) *************
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`

// ************* Step 2: Concatenate the string to be signed (essentially identical to the sample code) *************
String credentialScope = date + "/" + service + "/" + "tc3_request";
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
System.out.println(stringToSign);

// ************* Step 3: Calculate the signature (essentially identical to the sample code) *************
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);

// ************* Step 4: Concatenate Authorization (essentially identical to the sample code) *************
String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
System.out.println(authorization);

// ************* Step 5: Concatenate request headers (supplementary) *************
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);

// Use these headers to make network requests and access the relevant interfaces
//...Related network request code
}
}