Skip to content

Commit 9f70d1b

Browse files
committed
feat: cos 支持前端直传
1 parent 3f1e3ed commit 9f70d1b

2 files changed

Lines changed: 0 additions & 727 deletions

File tree

FileStorage/app/Utilities/CosUtility.php

Lines changed: 0 additions & 252 deletions
Original file line numberDiff line numberDiff line change
@@ -148,256 +148,4 @@ public static function getKeyAndCredentials(string $savePath)
148148
// 'resources' => $strategy->getStatements()[0]['resource'] ?? [],
149149
]);
150150
}
151-
152-
public static function getKeyAndCredentialsSuccessfulOnPublic(string $savePath)
153-
{
154-
$cosConfig = config('filesystems.disks.cos', []);
155-
156-
// 配置腾讯云COS信息
157-
$secretId = $cosConfig['secret_id'];
158-
$secretKey = $cosConfig['secret_key'];
159-
$bucket = sprintf('%s-%s', $cosConfig['bucket'], $cosConfig['app_id']); // 换成你的 bucket
160-
$region = $cosConfig['region']; // 换成 bucket 所在园区
161-
$expiredTime = 1800; // 策略过期时间(秒)
162-
163-
// 生成Policy
164-
$expiration = date('Y-m-d\TH:i:s\Z', time() + $expiredTime);
165-
$policy = [
166-
'expiration' => $expiration,
167-
'conditions' => [
168-
['bucket' => $bucket],
169-
// ['starts-with', '$key', $savePath], // 限制上传路径
170-
['content-length-range', 0, 10485760] // 限制文件大小10MB
171-
]
172-
];
173-
174-
// 将Policy转为JSON并Base64编码
175-
$policyJSON = json_encode($policy);
176-
$policyBase64 = base64_encode($policyJSON);
177-
178-
// 生成签名
179-
$signature = base64_encode(hash_hmac('sha1', $policyBase64, $secretKey, true));
180-
181-
// 构造返回数据
182-
$response = [
183-
'policy' => $policyBase64,
184-
'signature' => $signature,
185-
'secretId' => $secretId,
186-
'bucket' => $bucket,
187-
'region' => $region,
188-
'uploadUrl' => "https://{$bucket}.cos.{$region}.myqcloud.com",
189-
'cosHost' => "https://{$bucket}.cos.{$region}.myqcloud.com",
190-
];
191-
192-
$response['key'] = $savePath;
193-
194-
195-
196-
/** @var \Overtrue\Flysystem\Cos\CosAdapter */
197-
// $adapter = CosUtility::getStorage()->getAdapter();
198-
// $objectUrl = $adapter->getObjectClient()->getObjectUrl($savePath);
199-
// $objectUrl = sprintf("https://%s.cos.%s.myqcloud.com/%s", $bucket, $region, $savePath);
200-
// $signature = new \Overtrue\CosClient\Signature($cosConfig['secret_id'], $cosConfig['secret_key']);
201-
// $request = new \GuzzleHttp\Psr7\Request('POST', $objectUrl);
202-
// $signString = $signature->createAuthorizationHeader($request);
203-
// parse_str($signString, $signInfo);
204-
// dd($signInfo, $signString);
205-
// $response = array_merge($response, $signInfo);
206-
207-
208-
209-
// header('Content-Type: application/json');
210-
return $response;
211-
}
212-
213-
/**
214-
* 前端直传, 获取单一文件上传权限的临时密钥
215-
*
216-
* 需要再 bucket 的安全设置,允许 cors 跨域
217-
*
218-
* @param string $savePath
219-
* @return array
220-
*
221-
* @see https://cloud.tencent.com/document/product/436/9067#.E6.96.B9.E6.A1.88.E4.BC.98.E5.8A.BF
222-
*/
223-
public static function getKeyAndCredentialsFail(string $savePath)
224-
{
225-
$cosConfig = config('filesystems.disks.cos', []);
226-
if (empty($cosConfig)) {
227-
throw new \RuntimeException('请完善 cos 配置信息');
228-
}
229-
230-
$cosKey = $savePath;
231-
$bucket = sprintf('%s-%s', $cosConfig['bucket'], $cosConfig['app_id']); // 换成你的 bucket
232-
$region = $cosConfig['region']; // 换成 bucket 所在园区
233-
234-
/** @var \Overtrue\Flysystem\Cos\CosAdapter */
235-
$adapter = CosUtility::getStorage()->getAdapter();
236-
$objectUrl = $adapter->getObjectClient()->getObjectUrl($savePath);
237-
$objectUrl = sprintf("https://%s.cos.%s.myqcloud.com/%s", $bucket, $region, $savePath);
238-
239-
240-
$signature = new \Overtrue\CosClient\Signature($cosConfig['secret_id'], $cosConfig['secret_key']);
241-
$request = new \GuzzleHttp\Psr7\Request('POST', $objectUrl);
242-
$signString = $signature->createAuthorizationHeader($request);
243-
parse_str($signString, $signInfo);
244-
245-
246-
// 业务自行实现 用户登录态校验,比如对 token 校验
247-
// $canUpload = checkUserRole($userToken);
248-
// if (!$canUpload) {
249-
// return '当前用户没有上传权限';
250-
// }
251-
252-
// 上传文件可控制类型、大小,按需开启
253-
$permission = array(
254-
'limitExt' => false, // 限制上传文件后缀
255-
'extWhiteList' => ['jpg', 'jpeg', 'png', 'gif', 'bmp'], // 限制的上传后缀
256-
'limitContentType' => false, // 限制上传 contentType
257-
'limitContentLength' => false, // 限制上传文件大小
258-
);
259-
$condition = array();
260-
261-
// 客户端传进原始文件名,这里根据文件后缀生成随机 Key
262-
$ext = pathinfo($savePath, PATHINFO_EXTENSION);
263-
264-
// 1. 限制上传文件后缀
265-
if ($permission['limitExt']) {
266-
if ($ext === '' || array_key_exists($ext, $permission['extWhiteList'])) {
267-
throw new \RuntimeException('非法文件,禁止上传');
268-
}
269-
}
270-
271-
// 2. 限制上传文件 content-type
272-
if ($permission['limitContentType']) {
273-
// 只允许上传 content-type 为图片类型
274-
$condition['string_like_if_exist'] = array('cos:content-type' => 'image/*');
275-
}
276-
277-
// 3. 限制上传文件大小
278-
if ($permission['limitContentLength']) {
279-
// 上传大小限制不能超过 5MB(只对简单上传生效)
280-
$condition['numeric_less_than_equal'] = array('cos:content-length' => 5 * 1024 * 1024);
281-
}
282-
283-
$config = array(
284-
'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
285-
'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
286-
'proxy' => '',
287-
'secretId' => $cosConfig['secret_id'], // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
288-
'secretKey' => $cosConfig['secret_key'], // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
289-
'bucket' => $bucket, // 换成你的 bucket
290-
'region' => $region, // 换成 bucket 所在园区
291-
'durationSeconds' => 1800, // 密钥有效期
292-
'allowPrefix' => array($cosKey), // 只分配当前 key 的路径权限
293-
// 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
294-
'allowActions' => array(
295-
// // 这里可以从临时密钥的权限上控制前端允许的操作
296-
//'name/cos:*', // 这样写可以包含下面所有权限
297-
298-
// // 列出所有允许的操作
299-
// // ACL 读写
300-
// 'name/cos:GetBucketACL',
301-
// 'name/cos:PutBucketACL',
302-
// 'name/cos:GetObjectACL',
303-
// 'name/cos:PutObjectACL',
304-
// // 简单 Bucket 操作
305-
// 'name/cos:PutBucket',
306-
// 'name/cos:HeadBucket',
307-
// 'name/cos:GetBucket',
308-
// 'name/cos:DeleteBucket',
309-
// 'name/cos:GetBucketLocation',
310-
// // Versioning
311-
// 'name/cos:PutBucketVersioning',
312-
// 'name/cos:GetBucketVersioning',
313-
// // CORS
314-
// 'name/cos:PutBucketCORS',
315-
// 'name/cos:GetBucketCORS',
316-
// 'name/cos:DeleteBucketCORS',
317-
// // Lifecycle
318-
// 'name/cos:PutBucketLifecycle',
319-
// 'name/cos:GetBucketLifecycle',
320-
// 'name/cos:DeleteBucketLifecycle',
321-
// // Replication
322-
// 'name/cos:PutBucketReplication',
323-
// 'name/cos:GetBucketReplication',
324-
// 'name/cos:DeleteBucketReplication',
325-
// // 删除文件
326-
// 'name/cos:DeleteMultipleObject',
327-
// 'name/cos:DeleteObject',
328-
// 简单文件操作
329-
'name/cos:PutObject',
330-
'name/cos:PostObject',
331-
'name/cos:AppendObject',
332-
'name/cos:GetObject',
333-
'name/cos:HeadObject',
334-
'name/cos:OptionsObject',
335-
'name/cos:PutObjectCopy',
336-
'name/cos:PostObjectRestore',
337-
// 分片上传操作
338-
'name/cos:InitiateMultipartUpload',
339-
'name/cos:ListMultipartUploads',
340-
'name/cos:ListParts',
341-
'name/cos:UploadPart',
342-
'name/cos:CompleteMultipartUpload',
343-
'name/cos:AbortMultipartUpload',
344-
),
345-
);
346-
347-
if (!empty($condition)) {
348-
$config['condition'] = $condition;
349-
}
350-
351-
352-
$startTime = time();
353-
$expiredTime = 1800; // 策略过期时间(秒)
354-
$expiration = date('Y-m-d\TH:i:s\Z', $startTime + $expiredTime);
355-
356-
$policy = [
357-
'expiration' => $expiration,
358-
'conditions' => [
359-
['bucket' => $bucket],
360-
['q-sign-algorithm' => $signInfo['q-sign-algorithm']],
361-
['q-ak' => $signInfo['q-ak']],
362-
// ['starts-with', '$key', dirname($savePath)], // 限制上传路径
363-
// ['starts-with', '$key', $savePath], // 限制上传路径
364-
// ['content-length-range', 0, 10485760], // 限制文件大小10MB
365-
// ['eq', '$q-sign-time', $signInfo['q-sign-time']], // 这个格式
366-
['q-sign-time' => $signInfo['q-sign-time']], // 这样也可以
367-
]
368-
];
369-
370-
$sts = new \Plugins\FileStorage\Utilities\StsUtility();
371-
$tempKeys = $sts->getTempKeys($config);
372-
373-
374-
// 将Policy转为JSON并Base64编码
375-
$policyJSON = json_encode($policy);
376-
$policyBase64 = base64_encode($policyJSON);
377-
378-
$secretKey = $cosConfig['secret_key'];
379-
$signature = base64_encode(hash_hmac('sha1', $policyBase64, $secretKey, true));
380-
381-
$cosHost = sprintf("https://%s.cos.%s.myqcloud.com", $bucket, $region);
382-
$extra = [
383-
'cosHost' => $cosHost,
384-
'startTime' => $startTime,
385-
'bucket' => $bucket,
386-
'region' => $region,
387-
'key' => $cosKey,
388-
'policy' => $policyBase64,
389-
'secretId' => $cosConfig['secret_id'],
390-
'signature' => $signature,
391-
];
392-
393-
$resTemp = array_merge(
394-
$tempKeys,
395-
$extra,
396-
$signInfo
397-
);
398-
399-
// \info('cos temp sts', json_encode($resTemp, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));
400-
401-
return $resTemp;
402-
}
403151
}

0 commit comments

Comments
 (0)