SecretId = $SecretId; $this->SecretKey = $SecretKey; $this->endpoint = $endpoint; $this->service = $service; $this->version = $version; $this->region = $region; $this->proxy = $proxy; } /** * @param string $action 方法名称 * @param array $param 请求参数 * @return array * @throws Exception */ public function request($action, $param) { $param = array_filter($param, function ($a) { return $a !== null;}); if (!$param) $param = (object)[]; $payload = json_encode($param); $time = time(); $authorization = $this->generateSign($payload, $time); $header = [ 'Authorization: '.$authorization, 'Content-Type: application/json; charset=utf-8', 'X-TC-Action: '.$action, 'X-TC-Timestamp: '.$time, 'X-TC-Version: '.$this->version, ]; if($this->region) { $header[] = 'X-TC-Region: '.$this->region; } $res = $this->curl_post($payload, $header); return $res; } private function generateSign($payload, $time) { $algorithm = "TC3-HMAC-SHA256"; // step 1: build canonical request string $httpRequestMethod = "POST"; $canonicalUri = "/"; $canonicalQueryString = ""; $canonicalHeaders = "content-type:application/json; charset=utf-8\n"."host:".$this->endpoint."\n"; $signedHeaders = "content-type;host"; $hashedRequestPayload = hash("SHA256", $payload); $canonicalRequest = $httpRequestMethod."\n" .$canonicalUri."\n" .$canonicalQueryString."\n" .$canonicalHeaders."\n" .$signedHeaders."\n" .$hashedRequestPayload; // step 2: build string to sign $date = gmdate("Y-m-d", $time); $credentialScope = $date."/".$this->service."/tc3_request"; $hashedCanonicalRequest = hash("SHA256", $canonicalRequest); $stringToSign = $algorithm."\n" .$time."\n" .$credentialScope."\n" .$hashedCanonicalRequest; // step 3: sign string $secretDate = hash_hmac("SHA256", $date, "TC3".$this->SecretKey, true); $secretService = hash_hmac("SHA256", $this->service, $secretDate, true); $secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true); $signature = hash_hmac("SHA256", $stringToSign, $secretSigning); // step 4: build authorization $authorization = $algorithm ." Credential=".$this->SecretId."/".$credentialScope .", SignedHeaders=content-type;host, Signature=".$signature; return $authorization; } private function curl_post($payload, $header) { $url = 'https://'.$this->endpoint.'/'; $ch = curl_init($url); if ($this->proxy) { curl_set_proxy($ch); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { $errmsg = curl_error($ch); curl_close($ch); throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); $arr = json_decode($response, true); if ($arr) { if (isset($arr['Response']['Error'])) { throw new Exception($arr['Response']['Error']['Message']); } else { return $arr['Response']; } } else { throw new Exception('返回数据解析失败'); } } }