本章介绍HTTP调用方式,适用基于API URL发起HTTP/HTTPS POST请求的用户。
参数 | 说明 | 示例 | 是否必传 |
---|---|---|---|
Tenant-Id | 火山引擎申请的账号id/租户id(tenant_id),数字类型,如2100021,header传入。 | 2100021 | 是 |
Tenant-Ts | 当前时间戳,单位秒。 | 150345676 | 是 |
Tenant-Nonce | 随机字符串,可以使用当前时间戳。 | ab1234fs34dbkdsu | 是 |
Tenant-Signature | 旧版鉴权签名,如果使用SDK的话无需关注。 1. 火山引擎侧提供token。(token:分配给客户的secret-key,由字节侧提供,与火山引擎生成的AccessKey Secret不同,用于鉴权加密的密钥,每个租户独立分配,每个租户下所有项目的token相同)。 2. 获取当前时间戳(Tenant-Ts),并转成字符串。 3. 生成随机字符串(Tenant-Nonce)。 4. 按照token、body(请求体,需要序列化成字节流)、Tenant-Id、Tenant-Ts、Tenant-Nonce顺序,将各字段拼接在一起。5. 使用sha-256对拼接后的字段进行hash。 6. 将得到的hash结果按照16进制编码得到字符串(大小写不敏感),该字符串即为签名Tenant-Signature。 | 7a73b4193a46727 af2b7355757fc2e8 47c5659107d7a806 bdecd6e46cf9644ab | 是 |
Request-Id | 请求id,由客户方自己给出,只要保证每次请求的request-id唯一即可,不要求具体格式,但建议不要太长。 | 84kduxkls74lcdj73jdu3 | 是 |
Content-Type | 请求体序列化方式,支持“application/x-protobuf”和“application/json”,具体使用哪种参考每个接口的说明。 | application/json | 是 |
Accept | 返回体序列化方式,如果该header不存在,则使用“Content-Type”的序列化方式。 | application/json | 否 |
Go
import ( "crypto/sha256" "encoding/json" "fmt" "github.com/spf13/cast" "time" ) func main() { token := "xxx" // 由字节侧提供. tenantId := "xxx" // 租户id tenantTs := cast.ToString(time.Now().Unix()) // 当前时间戳 tenantNonce := cast.ToString(time.Now().UnixNano()) // 使用纳秒时间戳作为随机字符串 httpBody, _ := json.Marshal(map[string]interface{}{ // 示例用http body.真实请求请替换成实际使用的body. "user": map[string]string{ "uid": "123", }, }) sign := calSignature(token, tenantId, tenantTs, tenantNonce, httpBody) fmt.Println(fmt.Sprintf("sign: %s", sign)) } func calSignature(token, tenantId, tenantTs, tenantNonce string, httpBody []byte) string { //按照token,body,tenantId,tenantTs,tenantNonce顺序将各字段拼接在一起 shaHash := sha256.New() shaHash.Write([]byte(token)) shaHash.Write(httpBody) shaHash.Write([]byte(tenantId)) shaHash.Write([]byte(tenantTs)) shaHash.Write([]byte(tenantNonce)) //将sha256转成16进制字符串 signature := fmt.Sprintf("%x", shaHash.Sum(nil)) return signature }
Java
import com.alibaba.fastjson2.JSON; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.UUID; public class Main { public static void main(String[] args) { String token = "xxx"; // 由字节侧提供. String tenantId = "xxx"; // 租户id String tenantTs = Integer.toString((int) (System.currentTimeMillis() / 1000)); // 当前时间戳 String tenantNonce = UUID.randomUUID().toString().substring(0, 8); // 随机字符串 byte[] httpBody = JSON.toJSONBytes(new HashMap<>() {{ // 示例用http body.真实请求请替换成实际使用的body. put("user", new HashMap<>() {{ put("uid", "123"); }}); }}); String sign = calSignature(token, tenantId, tenantTs, tenantNonce, httpBody); System.out.printf("sign: %s", sign); } //根据token、tenant_id、tenantTs、tenantNonce、httpBody计算signature public static String calSignature(String token, String tenant_id, String tenantTs, String tenantNonce, byte[] httpBody) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); // 按照token、httpBody、tenant_id、ts、nonce的顺序拼接 // 本身为字符串的字段,需要使用utf-8方式编码成字节数组 // httpBody本身为bytes类型,因此无需编码 digest.update(token.getBytes(StandardCharsets.UTF_8)); digest.update(httpBody); digest.update(tenant_id.getBytes(StandardCharsets.UTF_8)); digest.update(tenantTs.getBytes(StandardCharsets.UTF_8)); digest.update(tenantNonce.getBytes(StandardCharsets.UTF_8)); // 将得到sha256使用16进制字符串表示 return bytes2Hex(digest.digest()); } catch (NoSuchAlgorithmException ignored) { return ""; } } public static String bytes2Hex(byte[] bts) { StringBuilder des = new StringBuilder(); String hex; for (byte bt : bts) { // 剔除负数强转成int后补上的"ffffff" hex = (Integer.toHexString(bt & 0xff)); // 始终用两个16进制代表一个byte,不够的在前面补“0” if (hex.length() == 1) { des.append("0"); } des.append(hex); } return des.toString(); } }
Python
import hashlib import json import string import time import random def cal_signature(token, tenant_id, tenant_ts, tenant_nonce, http_body): sha256 = hashlib.sha256() sha256.update(token.encode('utf-8')) sha256.update(http_body.encode('utf-8')) sha256.update(tenant_id.encode('utf-8')) sha256.update(tenant_ts.encode('utf-8')) sha256.update(tenant_nonce.encode('utf-8')) return sha256.hexdigest() if __name__ == '__main__': token = 'xxx' # 由字节侧提供. tenant_id = 'xxx' # 租户id tenant_ts = str(int(time.time())) # 当前时间戳 tenant_nonce = ''.join(random.sample(string.ascii_letters + string.digits, 8)) # 随机字符串 http_body = json.dumps({ # 示例用http body.真实请求请替换成实际使用的body. "user": { "uid": "123" } }) sign = cal_signature(token, tenant_id, tenant_ts, tenant_nonce, http_body) print('sign: ', sign)