文档中心 > 调用示例
调用示例

最近更新时间:2022-08-04

以下代码用于演示签名的生成方式、接口调用以及请求结果。本示例中使用测试数据展示,使用QueryCamera接口作为样例接口。在实际对接过程中,请注意使用对应环境的地址,并替换相关接口的参数信息。

JavaCode
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import sun.misc.BASE64Encoder;
 
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.SimpleTimeZone;
import java.util.stream.Collectors;
 
public class SignatureUtil {
 
    private final static String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
 
    // 紫光云账号下创建的AccessKey Id
    private static final String accessKeyId = "请根据实际填写";
    // 紫光云账号下创建的AccessKey Secret
    private static final String accessKeySecret = "请根据实际填写";
    // 请求方式根据实际填写
    private static final String method = "GET";
 
    // 以QueryCamera接口为例,其他接口请替换对应接口名称及接口参数
    public static void main(String[] args) throws Exception {
        // 请求参数
        // 包含 公共参数 和 接口参数
        JSONObject params = new JSONObject();
        // 以下为公共参数(除Signature)
        // 返回类型
        params.put("Format""json");
        // 接口版本号
        params.put("Version""2021-10-15");
        params.put("AccessKeyId", accessKeyId);
        // 签名方法
        params.put("SignatureMethod""HMAC-SHA1");
        // 请求发起时间
        params.put("Timestamp", generateTimestamp());
        // 签名版本号
        params.put("SignatureVersion""1.0");
        // 签名随机字符串
        params.put("SignatureNonce""6a6e0ca6-4557-11e5-86a2-b8e8563dc8d2");
        // 接口对应参数
        // 需要调用的接口名称,这里以查询摄像头信息为例
        params.put("Action""QueryCamera");
        // 紫光云openapi服务接入地址
        String endpoint = "https://api.unicloud.com/univms?";
 
        // 生成http请求url
        String url = endpoint + getUrl(params) + getSignature(params, accessKeySecret);
        System.out.println("请求地址 : " + url);
 
        // 发送GET请求
        String result = senRequest(url);
        JSONObject resultObject = JSON.parseObject(result);
        System.out.printf("请求结果 : " + resultObject);
    }
 
    // GET请求参数拼接转换
    public static String getUrl(JSONObject json) {
        List<String> urlParamList = json.keySet().stream().map(key -> encode(key) + "=" + encode(json.getString(key))).collect(Collectors.toList());
        String url = Joiner.on("&").join(urlParamList);
        return url;
    }
 
    // 签名生成
    public static String getSignature(JSONObject json, String accessKeySecret) throws Exception {
 
        // 使用UTF-8字符集对参数进行URL编码,同时处理参数中的特殊字符
        List<String> paramList = json.keySet().stream().map(key -> encode(key) + "=" + encode(json.getString(key))).collect(Collectors.toList());
 
        // 排序参数
        List<String> pList = paramList.stream().map(SignatureUtil::encode).sorted().collect(Collectors.toList());
 
        // 规范化请求参数
        String canonicalizedQueryString = Joiner.on("%26").join(pList);
        System.out.println("规范化参数 : " + canonicalizedQueryString);
 
        // 生成 stringToSign
        String stringToSign = Joiner.on("&").join(method, URLEncoder.encode("/""utf-8"), canonicalizedQueryString);
        System.out.println("stringToSign : " + stringToSign);
 
        // 生成 hmac
        String hmac = encode(HmacSHA1Encrypt(stringToSign, accessKeySecret + "&"));
        System.out.println("签名 : " + hmac);
 
        // 返回签名
        return "&Signature=" + hmac;
    }
 
    // 加密
    public static String HmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
 
        //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(encryptKey.getBytes(), "HmacSHA1");
 
        //生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance("HmacSHA1");
 
        //用给定密钥初始化 Mac 对象
        mac.init(secretKey);
 
        //完成 Mac 操作
        byte[] rawHmac = mac.doFinal(encryptText.getBytes());
 
        return new BASE64Encoder().encode(rawHmac);
    }
 
    // 使用UTF-8进行URL编码,并处理特殊字符
    public static String encode(String s) {
        try {
            return s != null ? URLEncoder.encode(s, "UTF-8").replace("+""%20")
                    .replace("*""%2A").replace("%7E""~") : null;
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }
 
    // 生成时间戳(标准时间)
    public static String generateTimestamp() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
        df.setTimeZone(new SimpleTimeZone(0"GMT"));
        return df.format(date);
    }
 
    // 发送请求
    public static String senRequest(String url) throws Exception {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(3000).build();
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(httpGet);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != 200) {
            httpGet.abort();
            throw new RuntimeException("HttpClient,error status code :" + statusCode);
        }
        HttpEntity entity = response.getEntity();
        String result = null;
        if (entity != null) {
            result = EntityUtils.toString(entity, "utf-8");
            EntityUtils.consume(entity);
            response.close();
            return result;
        else {
            return null;
        }
    }
}
PythonCode
# UTF-8 编码并处理特殊字符
def percent_encode(s):
    encoding = sys.stdin.encoding if sys.stdin.encoding is not None else 'UTF-8'
    res = urllib.parse.quote(s.encode('utf8').decode(encoding))
    res = res.replace('+''%20')
    res = res.replace('*''%2A')
    res = res.replace('%7E''~')
    return res
 
 
# 生成签名
def compute_signature(parameters, accesskey_secret):
    sorted_parameters = sorted(parameters.items(), key=lambda parameters: parameters[0])
 
    canonicalized_query_string = ''
    for (k, v) in sorted_parameters:
        canonicalized_query_string += '&' + percent_encode(k) + '=' + percent_encode(v)
 
    string_to_sign = 'GET&%2F&' + percent_encode(canonicalized_query_string[1:])
    print("##util 生成签名前字符串(signString): %s" % string_to_sign)
    = hmac.new((accesskey_secret + "&").encode('utf-8'), string_to_sign.encode('utf-8'), sha1)
 
    signature = base64.encodebytes(h.digest()).strip()
    return signature
 
 
# 生成Url
def compose_url(parameters, accesskey_secret, cdn_server_address):
    signature = compute_signature(parameters, accesskey_secret)
    print("##util 生成签名结果:%s" % signature)
    parameters['Signature'= signature
    url = cdn_server_address + "?" + urllib.parse.urlencode(parameters)
    print("##util 拼接url结果: %s" % url)
    return url
 
 
if __name__ == '__main__':
    # 紫光云账号下创建的AccessKey Id
    ak = '请根据实际填写'
    # 紫光云账号下创建的AccessKey Secret
    sk = '请根据实际填写'
    # 以QueryCamera接口为例,其他接口请替换对应接口名称及接口参数
    user_params = {
        # 以下为公共参数
        # 返回类型
        'Format''JSON',
        # 接口版本号
        'Version''2021-10-15',
        'AccessKeyId': ak,
        # 签名方法
        'SignatureMethod''HMAC-SHA1',
        # 请求发起时间
        'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        # 签名版本号
        'SignatureVersion''1.0',
        # 签名随机字符串
        'SignatureNonce''6a6e0ca6-4557-11e5-86a2-b8e8563dc8d2',
        # 接口对应参数
        # 需要调用的接口名称,这里以查询摄像头信息为例
        'Action''QueryCamera'
    }
 
    # 服务接入地址
    # 紫光云openapi服务接入地址 https://api.unicloud.com/univms
    url = compose_url(user_params, sk, "https://api.unicloud.com/univms")
    print("请求地址 : %s" % url)
    res = requests.get(url)
    print("请求结果 : %s" % res.text)

返回结果默认为JSON格式,样例如下:

结果样例
{
    "Code""0",
    "Data": {
        "PageNum"1,
        "CameraList": [{
            "GroupId""uni03411202109f70ec205",
            "Name""0001",
            "UpdateTime""2021-08-13T07:59:12Z",
            "GroupName""wjw-02",
            "DeviceId""f9e4137ac09f4b319b4f961532989c87",
            "StreamStatus""off",
            "Type""ipc",
            "DeviceStatus""unregistered",
            "ChannelId""0",
            "ManageStatus""stop",
            "GbDeviceId""01234567891312323233",
            "ParentId""f9e4137ac09f4b319b4f961532989c87",
            "CreateTime""2021-08-13T07:59:12Z",
            "ParentName""0001"
        }],
        "PageSize"20,
        "TotalCount"14,
        "PageTotal"1
    },
    "RequestId""601a692f-659e-44eb-b496-2c8decb64dcd"
}