123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <?php
- namespace app\utils\Service\Tencent;
- use Qcloud\Cos\Client;
- use QCloud\COSSTS\Sts;
- class CosService
- {
- private $config;
- public function __construct()
- {
- $this->config = get_addon_config('cos');
- }
- public function getToken()
- {
- $config = $this->stsToken();
- $uploadUrl = $this->config['uploadurl'];//上传域名因存储区域不同而节点不同
- $cdnUrl = $this->config['cdnurl'];//上传域名因存储区域不同而节点不同
- $appId = $this->config['appId'] ?? '';
- $bucket = $this->config['bucket'] ?? '';//存储桶,格式:BucketName-APPID
- $region = $this->config['region'] ?? '';
- $key = str_replace('-'.$appId,'',$bucket);//对象在存储桶中的位置,即对象键
- $tmpSecretId = $config['credentials']['tmpSecretId']; //使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048
- $tmpSecretKey = $config['credentials']['tmpSecretKey']; //使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048
- $tmpToken = $config['credentials']['sessionToken']; //使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048
- $cosClient = new Client(
- array(
- 'region' => $region,
- 'scheme' => 'https', //协议头部,默认为 http
- 'signHost' => true, //默认签入Header Host;您也可以选择不签入Header Host,但可能导致请求失败或安全漏洞,若不签入host则填false
- 'credentials'=> array(
- 'secretId' => $tmpSecretId,
- 'secretKey' => $tmpSecretKey,
- 'token' => $tmpToken)));
- ### 简单上传预签名
- try {
- $signedUrl = $cosClient->getPreSignedUrl('putObject', array(
- 'Bucket' => $bucket, //存储桶,格式:BucketName-APPID
- 'Key' => $key, //对象在存储桶中的位置,即对象键
- 'Body' => 'string',
- 'Params'=> array(), //http 请求参数,传入的请求参数需与实际请求相同,能够防止用户篡改此HTTP请求的参数,默认为空
- 'Headers'=> array(), //http 请求头部,传入的请求头部需包含在实际请求中,能够防止用户篡改签入此处的HTTP请求头部,默认已签入host
- ), '+10 minutes'); //签名的有效时间
- // 请求成功
- // 请求成功
- return [true,[
- 'bucket' => $bucket,
- 'region' => $region,
- 'uploadUrl' => $uploadUrl,
- 'cdnUrl' => $cdnUrl,
- 'signUrl' => $signedUrl,
- ]];
- } catch (\Exception $e) {
- // 请求失败
- return [false,$e->getMessage()];
- }
- }
- /**
- * 腾讯云预签名URL
- */
- public function getSignedUrl($dir = 'uploads/')
- {
- $uploadUrl = $this->config['uploadurl'];//上传域名因存储区域不同而节点不同
- $cdnUrl = $this->config['cdnurl'];//上传域名因存储区域不同而节点不同
- $secretId = $this->config['secretId'] ?? '';
- $secretKey = $this->config['secretKey'] ?? '';
- $bucket = $this->config['bucket'] ?? '';
- $region = $this->config['region'] ?? '';
- $time = time();
- // $cosClient = new Client([
- // 'region' => $region,
- // 'schema' => $ssl, //协议头部,默认为http
- // 'signHost' => true, //默认签入Header Host;您也可以选择不签入Header Host,但可能导致请求失败或安全漏洞,若不签入host则填false
- // 'credentials' => [
- // 'secretId' => $secretId,
- // 'secretKey' => $secretKey
- // ]
- // ]);
- try {
- // $signedUrl = $cosClient->getPreSignedUrl('putObject', [
- // 'Bucket' => $bucket, //存储桶,格式:BucketName-APPID
- // 'Key' => $dir, //对象在存储桶中的位置,即对象键
- // 'Body' => 'string',
- // 'Params' => [], //http 请求参数,传入的请求参数需与实际请求相同,能够防止用户篡改此HTTP请求的参数,默认为空
- // 'Headers' => [], //http 请求头部,传入的请求头部需包含在实际请求中,能够防止用户篡改签入此处的HTTP请求头部,默认已签入host
- // ], '+10 minutes'); //签名的有效时间
- //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
- $addTime = 30 * 60;//三十分钟
- $expiration = $this->gmt_iso8601($time + $addTime);
- $StartTimestamp = $time;
- $EndTimestamp = $StartTimestamp + $addTime;
- $KeyTime = "$StartTimestamp;$EndTimestamp";
- $conditions = [
- ['content-length-range', 0, 1048576000],//最大文件大小.用户可以自己设置
- ["bucket" => $bucket],
- ["starts-with", '$key', $dir],// 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
- ["q-sign-algorithm" => "sha1"],
- ["q-ak" => $secretId],
- ["q-sign-time" => $KeyTime]
- ];
- $arr = ['expiration' => $expiration, 'conditions' => $conditions];
- $policy = json_encode($arr);
- $policyBase64 = base64_encode($policy);
- // 签名
- $SignKey = hash_hmac('sha1', $KeyTime, $secretKey);
- $StringToSign = sha1($policy);
- $Signature = hash_hmac('sha1', $StringToSign, $SignKey);
- // 请求成功
- return [true, [
- 'upload_url' => $uploadUrl,
- 'cdn_url' => $cdnUrl,
- 'region' => $region,
- 'policy' => $policyBase64,
- 'q_sign_algorithm' => 'sha1',
- 'q_ak' => $secretId,
- 'q_key_time' => $KeyTime,
- 'q_signature' => $Signature,
- ]];
- } catch (\Exception $e) {
- return [false, $e->getMessage()];
- }
- }
- public function stsToken()
- {
- $uploadUrl = $this->config['uploadurl'];//上传域名因存储区域不同而节点不同
- $cdnUrl = $this->config['cdnurl'];//上传域名因存储区域不同而节点不同
- $secretId = $this->config['secretId'] ?? '';
- $secretKey = $this->config['secretKey'] ?? '';
- $bucket = $this->config['bucket'] ?? '';
- $region = $this->config['region'] ?? '';
- $sts = new Sts();
- $config = array(
- 'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
- 'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
- 'proxy' => '',
- 'secretId' => $secretId, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
- 'secretKey' => $secretKey, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
- 'bucket' => $bucket,//'test-1253653367', // 换成你的 bucket
- 'region' => $region,//'ap-guangzhou', // 换成 bucket 所在园区
- 'durationSeconds' => 1800, // 密钥有效期
- 'allowPrefix' => array('exampleobject.jpg','exampleobject.png','exampleobject/*'), // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
- // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
- 'allowActions' => array (
- // 简单上传
- 'name/cos:PutObject',
- 'name/cos:PostObject',
- // 分片上传
- 'name/cos:InitiateMultipartUpload',
- 'name/cos:ListMultipartUploads',
- 'name/cos:ListParts',
- 'name/cos:UploadPart',
- 'name/cos:CompleteMultipartUpload'
- ),
- // 临时密钥生效条件,关于condition的详细设置规则和COS支持的condition类型可以参考 https://cloud.tencent.com/document/product/436/71306
- // "condition" => array(
- // "ip_equal" => array(
- // "qcs:ip" => array(
- // "10.217.182.3/24",
- // "111.21.33.72/24",
- // )
- // )
- // )
- );
- // 获取临时密钥,计算签名
- $tempKeys = $sts->getTempKeys($config);
- return $tempKeys;
- }
- private function xml_parser($str)
- {
- $xml_parser = xml_parser_create();
- if (!xml_parse($xml_parser, $str, true)) {
- xml_parser_free($xml_parser);
- return $str;
- } else {
- $res = json_decode(json_encode(simplexml_load_string($str, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
- return $res['Message'] ?? '请求错误';
- }
- }
- /**
- * @param $time
- * @return string
- * @throws \Exception
- */
- private function gmt_iso8601($time)
- {
- $dtStr = date("c", $time);
- $dateTime = new \DateTime($dtStr);
- $expiration = $dateTime->format(\DateTime::ISO8601);
- $pos = strpos($expiration, '+');
- $expiration = substr($expiration, 0, $pos);
- return $expiration . "Z";
- }
- }
|