机器翻译报错AuthFailure.SignatureFailure?

  • 回答 (2)
  • 关注 (0)
  • 查看 (229)

下面的代码自己写的,报错AuthFailure.SignatureFailure,The provided credentials could not be validated. Please check your signature is correct.麻烦帮看看哪里的问题,谢谢

<?php
header('Content-type:text/html; Charset=utf-8');
$SecretId = 'xxx';
$SecretKey = 'xxx';
$uriData = 'tmt.tencentcloudapi.com';

$SourceText = "hello world!";
$Source = "en";
$Target = "zh";
$region = 'ap-chengdu';

$test = new fanyi($SecretId, $SecretKey, $uriData);
$ret = $test->translate($SourceText, $Source, $Target, $region);

$ret = json_decode($ret, true);
print_r($ret);

class fanyi {
	protected $SecretId;
	protected $SecretKey;
	public function __construct($SecretId, $SecretKey, $uriData) {
		$this->SecretId = $SecretId;
		$this->SecretKey = $SecretKey;
		$this->uriData = $uriData;
	}
	public function translate($SourceText, $Source, $Target, $region) {
		$arr = array(
			'Action' => 'TextTranslate',
			'ProjectId' => 0,
			'Region' => $region,
			'SecretId' => $this->SecretId,
			'SourceText' => urlencode($SourceText),
			'Source' => $Source,
			'Target' => $Target,
			'Nonce' => mt_rand(10000, 99999),
			'Timestamp' => time(),
			'Version' => '2018-03-21'
		);
        $arr['Signature'] = urlencode(self::sign($this->uriData, $arr, $this->SecretKey));
		print_r($arr);
		return self::curlPost("https://$this->uriData", $arr);
	}
	public static function sign($uriData, $params, $SecretKey){
		ksort($params, SORT_STRING);
		$params = http_build_query($params);
		$srcStr = "$uriData/?$params";
		$signStr = base64_encode(hash_hmac('sha1', $srcStr, $SecretKey, true));
		return $signStr;
	}
	public static function curlPost($url = '', $postData = '', $options = array()) {
		if (is_array($postData)) {
			$postData = http_build_query($postData, true);
		}
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		if (!empty($options)) {
			curl_setopt_array($ch, $options);
		}
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$data = curl_exec($ch);
		curl_close($ch);
		return $data;
	}
}
用户3347166用户3347166提问于
zqfan回答于
推荐

你这签名没有按照文档中要求的一步一步来啊:https://cloud.tencent.com/document/product/213/15693

1、拼接的时候是原文,但你却做了urlencode,而且还缺了应该在最前面的POST

2、signature总体上只需要做一次urlencode,但是做了两次,一次是显式的,一次是在http_build_query中隐式的,这个问题还在前面文档中专门强调了

有提供php sdk,其链接在每一个接口文档下面给出了,https://github.com/TencentCloud/tencentcloud-sdk-php。即使不想使用sdk,也有API Explorer提供签名的验证功能,其链接也在每一个接口文档下面给出了,https://console.cloud.tencent.com/api/explorer?Product=tmt&Version=2018-03-21&Action=TextTranslate。

用户3347166修改于

非常感谢,最主要是把前面的POST看漏了,就看了你的回答后也没有弄明白,后来研究了下面的python代码(不会python),才发现要把POST拼接到主机域名前面,汗,当然urlencode也是个问题.下面的代码是修改后的

<?php
header('Content-type:text/html; Charset=utf-8');
$SecretId = 'xxx';
$SecretKey = 'xxx';
$uriData = 'tmt.tencentcloudapi.com';

$SourceText = "hello world!";
$Source = "en";
$Target = "zh";
$region = 'ap-chengdu';

$test = new fanyi($SecretId, $SecretKey, $uriData);
$ret = $test->translate($SourceText, $Source, $Target, $region);

$ret = json_decode($ret, true);
print_r($ret);

class fanyi {
	protected $SecretId;
	protected $SecretKey;
	public function __construct($SecretId, $SecretKey, $uriData) {
		$this->SecretId = $SecretId;
		$this->SecretKey = $SecretKey;
		$this->uriData = $uriData;
	}
	public function translate($SourceText, $Source, $Target, $region) {
		$arr = array(
			'Action' => 'TextTranslate',
			'ProjectId' => 0,
			'Region' => $region,
			'SecretId' => $this->SecretId,
			'SourceText' => $SourceText,
			'Source' => $Source,
			'Target' => $Target,
			'Nonce' => mt_rand(10000, 99999),
			'Timestamp' => time(),
			'Version' => '2018-03-21'
		);
        $arr['Signature'] = self::sign('POST' . $this->uriData, $arr, $this->SecretKey);
		return self::curlPost("https://$this->uriData", $arr);
	}
	public static function sign($uriData, $params, $SecretKey){
		$params = self::formatQueryParaMap($params);
		$srcStr = "$uriData/?$params";
		$signStr = base64_encode(hash_hmac('sha1', $srcStr, $SecretKey, true));
		return $signStr;
	}
	protected static function formatQueryParaMap($paraMap, $urlEncode = false) {
		$buff = "";
		ksort($paraMap);
		foreach ($paraMap as $k => $v) {
				$v = self::auto_charset($v);
				if ($urlEncode) {
					$v = urlencode($v);
				}
				$buff .= $k . "=" . $v . "&";
		}
		$reqPar = '';
		if (strlen($buff) > 0) {
			$reqPar = substr($buff, 0, strlen($buff) - 1);
		}
		return $reqPar;
	}
	public static function curlPost($url = '', $postData = '', $options = array()) {
		if (is_array($postData)) {
			$postData = self::formatQueryParaMap($postData, true);
		}
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		if (!empty($options)) {
			curl_setopt_array($ch, $options);
		}
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		$data = curl_exec($ch);
		curl_close($ch);
		return $data;
	}
	public static function auto_charset($data, $to='utf-8') {
		if(is_string($data)) {
			$encode_arr = array('UTF-8','ASCII','GBK','GB2312','BIG5','JIS','eucjp-win','sjis-win','EUC-JP');
			$encoded = mb_detect_encoding($data, $encode_arr);
			$data = mb_convert_encoding($data, $to, $encoded);
			return $data;
		}else{
			return $data;
		}
	}
}

可能回答问题的人

  • Y. Ji

    5 粉丝0 提问1 回答
  • Superbeet

    4 粉丝0 提问0 回答
  • daiye

    1 粉丝0 提问0 回答
  • DJ213

    0 粉丝0 提问0 回答
  • 罗罗可爱多

    腾讯 · 高级研究员 (已认证)

    7 粉丝0 提问4 回答
  • 晏栋栋栋

    1 粉丝0 提问1 回答

扫码关注云+社区

领取腾讯云代金券