阿里云提供了部分语言的调用API方法,如果您使用别的语言来调用,则需要对该语言加签。
系统级Header
参数 | 是否必传 | 描述 |
X-Ca-Key | 是 | AppKey。 |
X-Ca-Signature | 是 | 签名字符串。 |
X-Ca-Timestamp | 否 | API调用者传递时间戳,值为当前时间的毫秒数,即从1970年1月1日起至今的时间转换为毫秒。时间戳有效时间为15分钟。 |
X-Ca-Nonce | 否 | API调用者生成的UUID,结合时间戳防重复。 |
X-Ca-Stage | 否 | 请求API所属Stage,目前仅支持TEST 、PRE和RELEASE,默认为RELEASE。 重要 若您调用非线上环境的API,请一定要指定该参数的值,否则会报URL错误。 |
签名校验
构建加密字符串。
String stringToSign= HTTPMethod + "\n" + Accept + "\n" + //建议显示设置Accept Header。当Accept为空时,部分Http客户端给Accept设置默认值*/*,会导致签名校验失败 Content-MD5 + "\n" Content-Type + "\n" + Date + "\n" + Headers + Url
其中,HTTPMethod为全大写,例如POST。Accept、Content-MD5、Content-Type、Date如果为空需要添加换行符\n。Headers如果为空不需要添加换行符\n。
Content-MD5:是指Body的MD5值,只有当Body非Form表单时才计算MD5,计算方式如下。
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8"))); //bodyStream为字节数组
Headers:是指参与签名计算的Header的
Key
、Value
拼接的字符串,建议对X-Ca开头的Header和自定义Header计算签名。Headers组织方法如下。
对参与签名计算的Header的
Key
按照字典排序后使用。如果某个Header的Value
为空,则使用HeaderKey + “:”+“\n”参与签名,需要保留Key和英文冒号。示例如下所示。String headers = HeaderKey1 + ":" + HeaderValue1 + "\n"\+ HeaderKey2 + ":" + HeaderValue2 + "\n"\+ ... HeaderKeyN + ":" + HeaderValueN + "\n"
此外,还需要将所有参与签名的Header的key拼接到一起(用英文冒号分隔,假设此处拼接得到的字符串为
Key1:Key2:Key3
),且在调用API的HTTP Request中添加对应的Header项,即X-Ca-Signature-Headers : Key1:Key2:Key3
。URL:指
Path+Query+Body
中Form参数,组织方法如下。对
Query+Form
参数按照字典对Key进行排序后,按照如下方法拼接,如果Query
或Form
参数为空,则URL=Path
,不需要添加,如果某个参数的Value
为空只保留Key
参与签名,等号则不需要再加入签名。String url = Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
计算签名。
Mac hmacSha256 = Mac.getInstance("HmacSHA256"); byte[] keyBytes = secret.getBytes("UTF-8"); //App端调用则为App的appsecret hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256")); String sign = new String(Base64.encodeBase64(hmacSha256.doFinal(stringToSign.getBytes("UTF-8")),"UTF-8"));
传递签名。
将计算的签名结果放到Request的Header中,
Key
为X-Ca-Signature。排查签名错误。
当签名校验失败时,API网关会将服务端的
StringToSign
放到HTTP Response的Header中返回到客户端,Key
为X-Ca-Error-Message。只需要将本地计算的StringToSign
与服务端返回的StringToSign
进行对比即可找到问题。如果服务端与客户端的StringToSign
一致,请检查用于签名计算的密钥是否正确。因为HTTP Header中无法表示换行,因此StringToSign中的换行符都被过滤掉了,对比时请忽略换行符。
签名Demo。
签名计算的详细Demo(JAVA),请参见api-gateway-demo-sign-java。