Skip to content

认证授权

获取访问凭证(推荐)

1.接口说明

接口路径:/api/user/v3/tokens

请求方式:POST

请求数据类型:application/json

接口描述:区域资源用户认证,认证成功后返回各区域ID、名称以及区域接口访问凭证token

备注:

1、每次访问为用户可用的计算区域分别颁发一个token,此token为访问其他服务接口的凭证,在后续接口请求中均需要携带。每个区域的token配合获取授权区域接口返回的URL地址,携带token调用作业、文件、容器等接口。

2、若用户有某个区域的访问权限,但账户状态为停用状态时,则返回区域信息,但token为null,无法调用后续接口,需充值后才能正常调用接口。

3、clusterId为0,clusterName为ac的区域信息为平台自身token,仅支持调用平台层面接口,如认证授权和用户资源及资源。

2.请求消息

参数说明: Headers:

名称类型必填描述示例
userstring用户名test
accessKeystringAK934e4dd887264b63a797ccb27f86048f
signaturestring签名b86b8b86c98ce...
timestampstring时间戳1764597591

3.签名算法

1. 获取授权码

在个人中心,点击【访问控制】,生成授权码下载并保存。 accessKey(AK)与 secretKey(SK)对应下载文件中的 Accesskey、Secretkey 列。

2. 签名生成流程:

  1. 构造请求参数:
  • 请求参数包括 accessKey(AK)、timestamp(当前秒级时间戳)、user(平台用户名)。
  • 构造JSON字符串如下,作为待签名的消息。
json
{"accessKey":"85f96a42b13f4d2c8b760d2775bbcca8","timestamp":"1764597591","user":"bob"}
  1. 生成签名:
  • 使用 HMAC-SHA256 算法对 JSON 字符串进行签名。
  • 使用 secretKey(SK)密钥,计算消息的签名。
  • 结果是一个 16 进制字符串,即签名。

3. 签名算法示例:

Java代码示例

java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class AkSkSignatureUtil {

    private static final String ALGORITHM = "HmacSHA256";

    /**
     * 构造待签名 JSON 字符串并生成签名
     *
     * @param accessKey AK
     * @param timestamp 时间戳(秒,字符串)
     * @param user      用户名
     * @param secretKey SK
     * @return 签名(小写十六进制)
     */
    public static String sign(String accessKey, String timestamp, String user, String secretKey) {
        // 按字典序拼接 JSON:accessKey, timestamp, user
        StringBuilder jsonBuilder = new StringBuilder();
        jsonBuilder.append("{\"accessKey\":\"")
                .append(escapeJson(accessKey))
                .append("\",\"timestamp\":\"")
                .append(escapeJson(timestamp))
                .append("\",\"user\":\"")
                .append(escapeJson(user))
                .append("\"}");

        String dataToSign = jsonBuilder.toString();

        return hmacSha256(secretKey, dataToSign);
    }

    private static String escapeJson(String input) {
        if (input == null) return "";
        return input.replace("\\", "\\\\").replace("\"", "\\\"");
    }

    private static String hmacSha256(String secret, String message) {
        try {
            Mac mac = Mac.getInstance(ALGORITHM);
            SecretKeySpec spec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), ALGORITHM);
            mac.init(spec);
            byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            throw new RuntimeException("Failed to generate HMAC-SHA256 signature", e);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString().toLowerCase();
    }

    // ========================
    // 示例使用
    // ========================
    public static void main(String[] args) {
        String accessKey = "your_access_key_here"; // 替换为真实的 AK
        String timestamp = "1764597591";           // 当前时间戳
        String user = "bob";                       // 用户名
        String secretKey = "your_secret_key_here"; // 替换为真实的 SK

        String signature = sign(accessKey, timestamp, user, secretKey);
        System.out.println("Generated Signature: " + signature);
    }
}

Python代码示例

python
import hmac
import hashlib

def escape_json(s: str) -> str:
    if s is None:
        return ""
    return s.replace("\\", "\\\\").replace('"', '\\"')

def sign(access_key: str, timestamp: str, user: str, secret_key: str) -> str:
    """
    构造待签名 JSON 字符串并生成 HMAC-SHA256 签名
    
    Args:
        access_key: AK
        timestamp: 时间戳(秒,字符串)
        user: 用户名
        secret_key: SK
    
    Returns:
        签名(小写十六进制字符串)
    """
    # 按字典序拼接 JSON:accessKey, timestamp, user
    escaped_ak = escape_json(access_key)
    escaped_ts = escape_json(timestamp)
    escaped_user = escape_json(user)
    
    data_to_sign = f'{{"accessKey":"{escaped_ak}","timestamp":"{escaped_ts}","user":"{escaped_user}"}}'
    
    # 计算 HMAC-SHA256 签名
    signature = hmac.new(
        key=secret_key.encode('utf-8'),
        msg=data_to_sign.encode('utf-8'),
        digestmod=hashlib.sha256
    ).hexdigest()
    
    return signature.lower()

# ========================
# 示例使用
# ========================
if __name__ == "__main__":
    access_key = "your_access_key_here"   # 替换为真实的 AK
    timestamp = "1764597591"              # 时间戳(秒)
    user = "bob"                          # 用户名
    secret_key = "your_secret_key_here"   # 替换为真实的 SK

    signature = sign(access_key, timestamp, user, secret_key)
    print("Generated Signature:", signature)

4.请求示例

CURL请求示例

shell
curl --location --request POST 'https://scnet-demo.accloud.cn/api/user/v3/tokens' \
--header 'accessKey: 934e4dd887264b63a797ccb27f86048f' \
--header 'signature: b2cfe85a136af1e3ff18898e' \
--header 'user: test' \
--header 'timestamp: 1764597591'

Java请求示例

java
import okhttp3.*;

public class GetUserTokenDemo {

    public static final String URL = "https://scnet-demo.accloud.cn/api/user/v3/tokens";
    
    public static final String USER = "test";
    
    public static final String ACCESS_KEY = "934e4dd887264b63a797ccb27f86048f";
    
    public static final String SIGNATURE = "6048ce7ba15c2af2e8cec12991ec13cf";
    
    public static final String TIMESTAMP = "1764597591";
    
    public static void main(String[] args) throws Exception {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "");
        Request request = new Request.Builder()
                .url(URL)
                .method("POST", body)
                .addHeader("user", USER)
                .addHeader("accessKey", ACCESS_KEY)
                .addHeader("signature", SIGNATURE)
                .addHeader("timestamp", TIMESTAMP)
                .build();
        Response response = client.newCall(request).execute();
        System.out.println(response.body().string());
    }
}

Python请求示例

python
import requests
import json

url = "https://scnet-demo.accloud.cn/api/user/v3/tokens"
payload = {}
headers = {
  "user": "test",
  "accessKey": "934e4dd887264b63a797ccb27f86048f",
  "signature": "6048ce7ba15c2af2e8cec12991ec13cf",
  "timestamp": "1764597591"
}

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

5.响应消息

返回参数:

名称类型描述示例
msgstring信息0
codestring状态码success
dataarray区域信息列表
clusterNamestring区域名称OpenAPI计算中心
clusterIdstring区域ID11112
tokenstring区域tokeneyJhbGciOiJIUzI1NiIsInR5cC...

返回示例:

json
{
  "msg":"success",
  "code":"0",
  "data":[
    {
      "clusterName":"OpenAPI计算中心",
      "clusterId":"11112",
      "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wdXRlVXNlciI6Imhhb3dqIiwiYWNjb3VudFN0YXR1cyI6Ik93ZSIsImNyZWF0b3IiOiJhYyIsInJvbGUiOiIxIiwiZXhwaXJlVGltZSI6IjE2MzQyODY2MDMwNjYiLCJjbHVzdGVySWQiOiIxMTEyNiIsImludm9rZXIiOiJ4eHl5YWdlYSIsInVzZXIiOiJoYW93aiJ9.mprLWvhNLNK1YuQVLewnJ7AG10K644g38xAt-xO3GwY"
    },
    {
      "clusterName":"test中心",
      "clusterId":"111131",
      "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wdXRlVXNlciI6Imhhb3dqIiwiYWNjb3VudFN0YXR1cyI6IkRpc2FibGUiLCJjcmVhdG9yIjoiYWMiLCJyb2xlIjoiMSIsImV4cGlyZVRpbWUiOiIxNjM0Mjg2NjAzMDgwIiwiY2x1c3RlcklkIjoiMTExMTMxIiwiaW52b2tlciI6Inh4eXlhZ2VhIiwidXNlciI6Imhhb3dqIn0.zKhISUwMa2Y16SH0LOBvfSJN_ctvABPUHMsjHj7vJfA"
    },
    {
      "clusterName":"ac",
      "clusterId":"0",
      "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wdXRlVXNlciI6Imhhb3dqIiwiYWNjb3VudFN0YXR1cyI6Ik93ZSIsImNyZWF0b3IiOiJhYyIsInJvbGUiOiIxIiwiZXhwaXJlVGltZSI6IjE2MzQyODY2MDMwODciLCJjbHVzdGVySWQiOiIxMTEyNSIsImludm9rZXIiOiJ4eHl5YWdlYSIsInVzZXIiOiJoYW93aiJ9.bIGdJpUoCZaKSJB71o_ZKUBzpcdW4_y54afU_arRDIQ"
    }
  ]
}

6.错误码

错误码说明
10001内部错误
10003参数不全
10004参数无效
10008权限不足
10009校验失败
0接口调用成功