关于腾讯云API接口鉴权v3 AuthFailure.SignatureFailure的问题;

最近项目有个删除上传到云点播的视频需求,由于本地php版本有点低(5.4+),SDK要求最低PHP5.6.33,所以只能根据API自己来;调用API最关键的部分恐怕就是这个【接口鉴权】的问题了,下面简单说一下本地实践中小田遇到的坑:

错误代码:AuthFailure.SignatureFailure (签名错误)

{"Response":{"Error":{"Code":"AuthFailure.SignatureFailure","Message":"The provided credentials could not be validated. Please check your signature is correct."},"RequestId":"1c56be9c-844f-43bf-ac2a-587be2b5aa7a"}}

于是小田我开始问度娘,然而并没有找到理想的解决方案,只能自己来了...

还好的是腾讯云提供了自己的工具 API Explorer 供用户在线调用、签名验证、生成 SDK 代码;

腾讯同时提供了各种语言生成密钥的demo,以下为PHP对应demo

<?php
$secretId = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE";
$secretKey = "Gu5t9xGARNpq86cd98joQYCN3EXAMPLE";
$host = "cvm.tencentcloudapi.com";
$service = "cvm";
$version = "2017-03-12";
$action = "DescribeInstances";
$region = "ap-guangzhou";
// $timestamp = time();
$timestamp = 1551113065;
$algorithm = "TC3-HMAC-SHA256";

// step 1: build canonical request string
$httpRequestMethod = "POST";
$canonicalUri = "/";
$canonicalQueryString = "";
$canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$host."\n";
$signedHeaders = "content-type;host";
$payload = '{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}';
$hashedRequestPayload = hash("SHA256", $payload);
$canonicalRequest = $httpRequestMethod."\n"
    .$canonicalUri."\n"
    .$canonicalQueryString."\n"
    .$canonicalHeaders."\n"
    .$signedHeaders."\n"
    .$hashedRequestPayload;
echo $canonicalRequest.PHP_EOL;

// step 2: build string to sign
$date = gmdate("Y-m-d", $timestamp);
$credentialScope = $date."/".$service."/tc3_request";
$hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
$stringToSign = $algorithm."\n"
    .$timestamp."\n"
    .$credentialScope."\n"
    .$hashedCanonicalRequest;
echo $stringToSign.PHP_EOL;

// step 3: sign string
$secretDate = hash_hmac("SHA256", $date, "TC3".$secretKey, true);
$secretService = hash_hmac("SHA256", $service, $secretDate, true);
$secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
$signature = hash_hmac("SHA256", $stringToSign, $secretSigning);
echo $signature.PHP_EOL;

// step 4: build authorization
$authorization = $algorithm
    ." Credential=".$secretId."/".$credentialScope
    .", SignedHeaders=content-type;host, Signature=".$signature;
echo $authorization.PHP_EOL;

$curl = "curl -X POST https://".$host
    .' -H "Authorization: '.$authorization.'"'
    .' -H "Content-Type: application/json; charset=utf-8"'
    .' -H "Host: '.$host.'"'
    .' -H "X-TC-Action: '.$action.'"'
    .' -H "X-TC-Timestamp: '.$timestamp.'"'
    .' -H "X-TC-Version: '.$version.'"'
    .' -H "X-TC-Region: '.$region.'"'
    ." -d '".$payload."'";
echo $curl.PHP_EOL;

问题就来了,按照官方demo,最后通过php的cUrl提交时,出现签名错误的返回;

其中曲折这里我就不一一吐槽了,直接讲重点了,以下地方请格外注意:

1、demo中的

$payload = '{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}';

变量看着是个JSON格式,实际是个string,请使用json_encode(array)的形式转换自己的POST数据;比如小田我调用的是删除视频接口 需要传参如下  $payload = json_encode(['FileId'=>$FileId]);

2、demo中的step2里面的$canonicalHeaders与 API Explorer 中的对应部分不一样,API Explorer 中不包含charset=utf-8字符编码字段,导致第二步生成的$hashedRequestPayload 与 API Explorer 生成的不一致,demo中的可以去掉,注意:请将前面的“;”一同去掉;

3、圈重点:上面两步确定没问题的时候,签名部分基本结束;但是通过 Curl 提交依然出错;原因如下:

这是由于demo中step2中$canonicalHeaders变量我们去掉了【; charset=utf-8】部分造成的;重点!!!请求头中的这部分一定要与demo中step2步骤的$canonicalHeaders保持一致;如果上面去掉了【; charset=utf-8】,这里也需要去掉,如果上面不去掉这里也不要去掉,【; charset=utf-8】中“;”与“charset=utf-8”之间的空格 也要一样,上面有空格下面也需要有,不然就会提示 签名错误。。。血淋淋的教训,希望各位PHP攻城狮引以为戒。

 

  • 2
    点赞
  • 7
    收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 7

打赏作者

别吃我的毒蘑菇

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值