腾讯云 API 会对每个访问的请求进行身份验证,即每个请求都需要在公共请求参数中包含签名信息(Signature)以验证用户身份。签名信息由用户所执有的安全凭证生成,安全凭证包括 SecretId 和 SecretKey,若用户还没有安全凭证,则需要在腾讯云官网上自主申请,否则就无法调用云 API 接口。
签名算法说明
CMQ 支持客户端使用 SHA1 和 SHA256 两种签名方式,用户可以通过参数 SignatureMethod 指定签名方法,如果该参数值为 HmacSHA256 则使用 SHA256 签名。 若该参数不传,或者值不等于 HmacSHA256 则统一使用 SHA1 计算签名。
1. 申请安全凭证
在第一次使用云 API 之前,用户需要在腾讯云控制台上申请安全凭证。安全凭证包括 SecretId 和 SecretKey,其中 SecretId 是用于标识 API 调用者身份的,SecretKey 是用于加密签名字符串和服务器端验证签名字符串的密钥。用户应严格保管其 SecretKey,避免泄露。
申请安全凭证的具体步骤如下:
1.1 登录 腾讯云管理中心控制台。
1.2 单击【云产品】,选择【管理与审计】栏下的【访问密钥】,进入云 API 密钥管理页面。
1.3 在 云 API 访问密钥管理 页面,单击【新建】即可以创建一对 SecretId/SecretKey,每个账号最多可以拥有两对 SecretId/SecretKey。
2. 生成签名串
有了安全凭证 SecretId 和 SecretKey 后,就可以生成签名串了。下面给出了一个生成签名串的详细过程。
假设用户的 SecretId 和 SecretKey 分别是:
- SecretId:
AKIDPcY*****CVYLn3zT
- SecretKey:
pPgfLip*****aU7UbQyFFx
注意:这里只是示例,请用户根据自己实际的 SecretId 和 SecretKey 进行后续操作。
以发送消息接口举例(SendMessage)请求为例,当用户调用这一接口时,其请求参数可能如下:
参数名称 | 中文 | 参数值 |
---|---|---|
Action | 方法名 | SendMessage |
SecretId | 密钥 ID | AKIDPcY*****CVYLn3zT |
Timestamp | 当前时间戳 | 1534154812 |
SignatureMethod | 签名使用的方法 | HmacSHA1 |
Nonce | 随机正整数 | 2889712707386595659 |
queueName | 发送消息的队列名称 | test1 |
RequestClient | 客户端版本 | SDK_Python_1.3 |
clientRequestId | 客户端自定义唯一 ID | 123***1231 |
delaySeconds | 延时时间 | 0 |
msgBody | 发送的消息内容 | msg |
由上表可以看出,请求参数中的公共请求参数只有5个:Action、SecretId、Timestamp、Nonce 、SignatureMethod,而不是在“公共请求参数”中所述的 6 个,事实上,第 6 个参数 Signature(签名串)正是由其他参数(包括指令请求参数)共同生成的,具体步骤如下:
2.1. 对参数排序
首先对所有请求参数按参数名做字典序升序排列,所谓字典序升序排列,直观上就如同在字典中排列单词一样排序,按照字母表或数字表里递增顺序的排列次序,即先考虑第一个“字母”,在相同的情况下考虑第二个“字母”,依此类推。您可以借助编程语言中的相关排序函数来实现这一功能,如 PHP 中的 ksort 函数。上述示例参数的排序结果如下:
Action=SendMessage
Nonce=2889712707386595659
RequestClient=SDK_Python_1.3
SecretId=AKIDPcY*****CVYLn3zT
SignatureMethod=HmacSHA1
Timestamp=1534154812
clientRequestId=123***1231
delaySeconds=0
msgBody=msg
queueName=test1
使用其它程序设计语言开发时, 可对上面示例中的参数进行排序,得到的结果一致即可。
2.2. 拼接请求字符串
此步骤生成请求字符串。
将把上一步排序好的请求参数格式化成“参数名称”=“参数值”的形式,如对 Action 参数,其参数名称为"Action",参数值为"SendMessages",因此格式化后就为 Action=SendMessage。
注意:
- “参数值”为原始值而非 url 编码后的值。
- 若输入参数中包含下划线,则需要将其转换为“.”。
然后将格式化后的各个参数用"&"拼接在一起,最终生成的请求字符串为:
Action=SendMessage&Nonce=2889712707386595659&RequestClient=SDK_Python_1.3&SecretId=AKIDPcY*****CVYLn3zT&SignatureMethod=HmacSHA1&Timestamp=1534154812&clientRequestId=123***1231&delaySeconds=0&msgBody=msg&queueName=test1
2.3. 拼接签名原文字符串
此步骤生成签名原文字符串。
签名原文字符串由以下几个参数构成:
- 请求方法:支持 POST 和 GET 方式, 这里使用 GET 请求, 注意方法为全大写。
- 请求域名:这里假设请求广州地域cmq内网域名:cmq-queue-gz.api.tencentyun.com。
- 请求路径:云 API 的请求路径固定为
/v2/index.php
。 - 请求字符串:即上一步生成的请求字符串。
签名原文串的拼接规则为:请求方法 + 请求主机 +请求路径 + ? + 请求字符串
示例的拼接结果为:
POSTcmq-queue-gz.api.tencentyun.com/v2/index.php?Action=SendMessage&Nonce=2889712707386595659&RequestClient=SDK_Python_1.3&SecretId=AKIDPcY*****CVYLn3zT&SignatureMethod=HmacSHA1&Timestamp=1534154812&clientRequestId=123***1231&delaySeconds=0&msgBody=msg&queueName=test1
2.4. 生成签名串
此步骤生成签名串。
首先使用 HMAC-SHA1 算法对上一步中获得的 签名原文字符串 进行签名,然后将生成的签名串使用 Base64 进行编码,即可获得最终的签名串。
具体代码如下,以 PHP 语言为例:
$secretKey = 'pPgfLipfEXZ7VcRzhAMIyPaU7UbQyFFx';
$srcStr = 'POSTcmq-queue-gz.api.tencentyun.com/v2/index.php?Action=SendMessage&Nonce=2889712707386595659&RequestClient=SDK_Python_1.3&SecretId=AKIDPcY*****CVYLn3zT&SignatureMethod=HmacSHA1&Timestamp=1534154812&clientRequestId=123***1231&delaySeconds=0&msgBody=msg&queueName=test1';
$signStr = base64_encode(hash_hmac('sha1', $srcStr, $secretKey, true));
echo $signStr;
最终得到的签名串为:
C16WEtEXsD5v5tnaUMLAbZewXhI=
使用其它程序设计语言开发时, 可用上面示例中的原文进行签名验证, 得到的签名串与例子中的一致即可。
3. 签名串编码
注意:
- 生成的签名串并不能直接作为请求参数,需要对其进行 URL 编码。
- 如果用户的请求方法是 GET,则对所有请求参数值均需要做 URL 编码。
如上一步生成的签名串为 C16WEtEXsD5v5tnaUMLAbZewXhI=
,则其编码后为 C16WEtEXsD5v5tnaUMLAbZewXhI%3d
。因此,最终得到的签名串请求参数(Signature)为:C16WEtEXsD5v5tnaUMLAbZewXhI%3d
,它将用于生成最终的请求 URL。
最终的请求字符串为:
clientRequestId=1231231231&Nonce=2889712707386595659&Timestamp=1534154812&msgBody=msg&Action=SendMessage&SignatureMethod=HmacSHA1&RequestClient=SDK_Python_1.3&Signature=C16WEtEXsD5v5tnaUMLAbZewXhI%3D&delaySeconds=0&SecretId=AKIDPcY*****CVYLn3zT&queueName=test1