Move all domain folders from src/AKSRT/{Domain} to src/{Domain}; remap
Composer PSR-4 "AKSRT\\": "src/"; update audit script + README + ADR
paths; remove dead tools/build-psr4-map.php (scanned deleted inc/classes).
85 lines
2.5 KiB
PHP
85 lines
2.5 KiB
PHP
<?php
|
|
/**
|
|
* @package AKSRT
|
|
*/
|
|
|
|
namespace AKSRT\Sms;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
class SMSSignatureHelper {
|
|
|
|
/**
|
|
* 生成签名并发起请求
|
|
*
|
|
* @param string $accessKeyId AccessKeyId
|
|
* @param string $accessKeySecret AccessKeySecret
|
|
* @param string $domain API 域名
|
|
* @param array $params API 参数
|
|
* @param bool $https 是否使用 HTTPS
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function request(string $accessKeyId, string $accessKeySecret, string $domain, array $params, bool $https = true) {
|
|
$apiParams = array_merge([
|
|
'SignatureMethod' => 'HMAC-SHA1',
|
|
'SignatureNonce' => uniqid((string) mt_rand(0, 0xffff), true),
|
|
'SignatureVersion' => '1.0',
|
|
'AccessKeyId' => $accessKeyId,
|
|
'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
|
|
'Format' => 'JSON',
|
|
], $params);
|
|
|
|
ksort($apiParams);
|
|
|
|
$sortedQueryString = '';
|
|
foreach ($apiParams as $key => $value) {
|
|
$sortedQueryString .= '&' . $this->encode($key) . '=' . $this->encode((string) $value);
|
|
}
|
|
|
|
$stringToSign = 'POST&%2F&' . $this->encode(substr($sortedQueryString, 1));
|
|
$sign = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
|
|
$signature = $this->encode($sign);
|
|
|
|
$url = ($https ? 'https' : 'http') . "://{$domain}/";
|
|
$body = "Signature={$signature}{$sortedQueryString}";
|
|
|
|
return $this->fetchContent($url, $body);
|
|
}
|
|
|
|
/**
|
|
* URL 编码(对齐阿里云规范)
|
|
*/
|
|
private function encode(string $str): string {
|
|
$res = rawurlencode($str);
|
|
$res = str_replace('+', '%20', $res);
|
|
$res = str_replace('*', '%2A', $res);
|
|
$res = str_replace('%7E', '~', $res);
|
|
return $res;
|
|
}
|
|
|
|
/**
|
|
* 发送 HTTP POST 请求
|
|
*
|
|
* @return array|\WP_Error
|
|
*/
|
|
private function fetchContent(string $url, string $body) {
|
|
$response = wp_remote_post($url, [
|
|
'timeout' => 10,
|
|
'headers' => [
|
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
'x-sdk-client' => 'php/2.0.0',
|
|
],
|
|
'body' => $body,
|
|
]);
|
|
|
|
if (is_wp_error($response)) {
|
|
return $response;
|
|
}
|
|
|
|
$content = wp_remote_retrieve_body($response);
|
|
$decoded = json_decode($content, true);
|
|
|
|
return is_array($decoded) ? $decoded : ['raw' => $content];
|
|
}
|
|
}
|