踩坑记:C#访问阿里云的API小结,阿里云的文档有待改善……

为运维管理方便需要,写了一个小工具去调用阿里云的API,包括操作ECS、SLB、域名等等API,结果就这么一点点小东西,也被阿里云的文档坑了好多次,下面5个问题,有3个跟阿里云文档相关……
关键是阿里云的客服服务还差……

1、计算签名的AccessKeySecret不能直接用,要在末尾添加一个 &

比如AccessKeySecret是“testsecret”,那么用于计算 HMAC 的 Key 为 “testsecret&”
这个很让我无语,为啥要加这个玩意?AccessKeySecret已经是30个字符的随机串了,想当然的直接拿去计算,文档里虽然写了,但是稍不留神就会遗漏……


2、阿里云的文档上给出的签名值是错误的,这个没人校验吗?

参考文档:https://help.aliyun.com/document_detail/42884.html
踩坑记:C#访问阿里云的API小结,阿里云的文档有待改善……_第1张图片
这里文档上给出的源串是:
GET&%2F&AccessKeyId%3Dtestid%26Action%3DCheckDomain%26Format%3DJSON%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D5033a7d9-dfeb-417d-9fdf-13459fe90c1a%26SignatureVersion%3D1.0%26TimeStamp%3D2016-05-19T09%253A06%253A05Z%26Version%3D2016-05-11
算出的签名应该是:rdQZIariLRvk14Mmfc5YvAA6GwQ=
但是文档上说是:WXkgFH4ymmnCjSUM65f6I1n7%2FUs=
被坑的半死,还好没再去验证这个源串,直接调用API,是成功的……
而且,阿里云网页上的智能顾问,回答这个签名问题时,给出的签名结果也是错误的,并且,签名的相关描述,可以搜索出很多个结果,每个结果都有差异,有的居然没有UrlEncode……
还好实际的API调用是统一的,没有区别,阿里云内部文档真够混乱的:
踩坑记:C#访问阿里云的API小结,阿里云的文档有待改善……_第2张图片


3、不同区域的api域名还不一样,最坑的是阿里云找不到任何这方面的资料

比如获取slb信息的接口,API概览和API具体描述里的Demo,都明确写着:
Endpoint:负载均衡API的服务接入地址为slb.aliyuncs.com
https://help.aliyun.com/document_detail/27568.html
https://help.aliyun.com/document_detail/27582.html
实际上,用这个地址获取华南的slb能正常,获取其它地方,比如华北3(张家口)或德国的slb,永远是获取不到的……
后来怀疑是我的调用方式不对,就下载阿里云的SDK测试了一下,居然能获取到,
抓包看了一下,发现阿里云的SDK是发起了2次http请求,先查Endpoint,再查具体的api:
就是这个接口查Endpoint: http://location.aliyuncs.com/?Version=2015-06-12&Action=DescribeEndpoints
好吧,我用关键字:DescribeEndpoints 去阿里查一查,居然没有结果:
踩坑记:C#访问阿里云的API小结,阿里云的文档有待改善……_第3张图片
另外,阿里云的SDK也有bug,会缓存,我如果先读取华南的SLB,再获取华北的SLB,它就读取不到数据了……


4、HMAC计算出的签名含有+=/等特殊字符,提交前要UrlEncode

这个是我的错,之前做的接口签名都是MD5签名,不存在特殊字符,直接拼接就ok了,阿里云使用的是HMAC签名,结果可能出现特殊字符,导致我在调用时,有时正常,有时出错,被这问题纠结了半天,才通过抓包发现


5、C#的UrlEncode,特殊字符是小写,阿里云要求大写

比如等号=, C#的UrlEncode得出的结果是 %3d,但是阿里云要求用 %3D,这个只能自己重写一下UrlEncode了,参考代码如下:

/// 
/// 阿里云要求的UrlEncode是大写的……
/// 
/// 
/// 
private static String PercentEncode(String value)
{
    if (string.IsNullOrEmpty(value))
        return "";
    var lowStr = HttpUtility.UrlEncode(value, Encoding.UTF8);

    // HttpUtility.UrlEncode编码值为小写,要转换为大写
    var sb = new StringBuilder(lowStr);
    int i = lowStr.IndexOf('%'), j = sb.Length;
    while (i >= 0 && i + 2 < j) // 找到%,且后面还有2个字符时进入循环
    {
        if (sb[i + 1] >= 'a')
            sb[i + 1] = (char)(sb[i + 1] - 32);
        if (sb[i + 2] >= 'a')
            sb[i + 2] = (char)(sb[i + 2] - 32);
        i = lowStr.IndexOf('%', i + 2);
    }
    sb.Replace("+", "%20").Replace("*", "%2A").Replace("%7E", "~");
    return sb.ToString();
}

暂时就这5个坑,后面再发现再补上

你可能感兴趣的:(.Net技术)