diff --git a/src/Utils/Service/OssService.php b/src/Utils/Service/OssService.php new file mode 100644 index 0000000..afd3f43 --- /dev/null +++ b/src/Utils/Service/OssService.php @@ -0,0 +1,131 @@ + + * Powered by PhpStorm + * Created on 2022/5/11 + */ + +namespace Singularity\HDK\Utils\Service; + +use Hyperf\Utils\Codec\Json; + +class OssService +{ + /** + * @const 30s 过期 + */ + public const EXPIRE = 30; + + protected string $accessKeyId; + protected string $accessKeySecret; + protected string $host; + + public function __construct() + { + $this->accessKeyId = config('common.third_party.storage.oss.access_key_id'); + $this->accessKeySecret = config('common.third_party.storage.oss.access_key_secret'); + $this->host = config('common.third_party.storage.oss.oss_host'); + } + + /** + * 生成签证 + * + * @param string|null $dir + * @param bool $isImage + * @param int $maxFileSize 最大文件大小(单位:b) + * + * @return array + */ + public function generatePolicy( + string $dir = null, + bool $isImage = false, + int $maxFileSize = 1048576000 + ): array { + $expire_time = time() + self::EXPIRE; + $expiration = $this->gmtIso8601($expire_time); + + //最大文件大小.用户可以自己设置 + $condition = [ + 0 => 'Content-Length-Range', + 1 => 0, + 2 => $maxFileSize, + ]; + $conditions[] = $condition; + + // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。 + if ($dir) { + $start = [ + 0 => 'starts-with', + 1 => '$key', + 2 => $dir, + ]; + $conditions[] = $start; + } + + + $policy = Json::encode([ + 'expiration' => $expiration, + 'conditions' => $conditions, + ]); + $base64_policy = base64_encode($policy); + $string_to_sign = $base64_policy; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + $callback = Json::encode([ + 'callbackUrl' => config('oss_callback'), + 'callbackBody' => $isImage ? <<<'callbackBody' +{ + "bucket": ${bucket}, + "object": ${object}, + "etag": ${etag}, + "size": ${size}, + "mimeType": ${mimeType}, + "imageInfo": { + "height": ${imageInfo.height}, + "width": ${imageInfo.width}, + "format": ${imageInfo.format} + }, + "uid": ${x:uid}, + "name": ${x:name}, + "hash": ${x:hash} +} +callbackBody: <<<'callbackBody' +{ + "bucket": ${bucket}, + "object": ${object}, + "etag": ${etag}, + "size": ${size}, + "mimeType": ${mimeType}, + "uid": ${x:uid}, + "name": ${x:name}, + "hash": ${x:hash} +} +callbackBody, + 'callbackBodyType' => 'application/json', + ]); + + return [ + 'accessid' => $this->accessKeyId, + 'host' => $this->host, + 'policy' => $base64_policy, + 'signature' => $signature, + 'expire' => $expire_time, + 'dir' => $dir, + 'callback' => base64_encode($callback), + ]; + } + + /** + * 将时间戳转化为 ISO8601 格式 + * + * @param int $time + * + * @return string + */ + protected function gmtIso8601(int $time): string + { + return str_replace('+00:00', '.000Z', gmdate('c', $time)); + } +} \ No newline at end of file