<?php
namespace app\adminapi\controller;
use hg\apidoc\annotation as Apidoc;
use think\facade\Config;
/**
*
* @Apidoc\Title("腾讯云临时密钥模块")
*
*/
class QcloudTemporaryKey
{
//
/**
* @Apidoc\Title("获取腾讯云临时密钥接口")
* @Apidoc\Desc("")
* @Apidoc\Url("/adminapi/getQcloudTempKeys")
* @Apidoc\Method("GET")
* @Apidoc\Tag("")
* @Apidoc\Header("Authorization", type="string",require="true", desc="授权token")
* @Apidoc\Returned("code", type="int",default="200", desc="成功码")
* @Apidoc\Returned("msg", type="string",default="请求成功",desc="成功或错误提示")
* @Apidoc\Returned("data", type="object", desc="返回数据",
* @Apidoc\Returned("credentials", type="object",desc="",
* @Apidoc\Returned("sessionToken", type="string",default="", desc=""),
* @Apidoc\Returned("tmpSecretId", type="string",default="", desc=""),
* @Apidoc\Returned("tmpSecretKey", type="string",default="", desc=""),
* ),
* @Apidoc\Returned("expiredTime", type="string",default="", desc=""),
* )
*/
public function getQcloudTempKeys() {
$config = array(
'Url' => 'https://sts.api.qcloud.com/v2/index.php',
'Domain' => 'sts.api.qcloud.com',
'Proxy' => '',
'SecretId' => Config::get('upload.qcloudcos.secret_id'), // 固定密钥
'SecretKey' => Config::get('upload.qcloudcos.secret_key'), // 固定密钥
'Bucket' => Config::get('upload.qcloudcos.bucket'),
'Region' => Config::get('upload.qcloudcos.region'),//存储桶的地域
'AllowPrefix' => '*', // 必填,这里改成允许的路径前缀,这里可以根据自己网站的用户登录态判断允许上传的目录,例子:* 或者 a/* 或者 a.jpg
);
// 判断是否修改了 AllowPrefix
if ($config['AllowPrefix'] === '_ALLOW_DIR_/*') {
return returnErrorJson('请修改 AllowPrefix 配置项,指定允许上传的路径前缀');
}
$ShortBucketName = substr($config['Bucket'],0, strripos($config['Bucket'], '-'));
$AppId = substr($config['Bucket'], 1 + strripos($config['Bucket'], '-'));
$policy = array(
'version'=> '2.0',
'statement'=> array(
array(
'action'=> array(
// // 这里可以从临时密钥的权限上控制前端允许的操作
//'name/cos:*', // 这样写可以包含下面所有权限
// // 列出所有允许的操作
// // ACL 读写
// 'name/cos:GetBucketACL',
// 'name/cos:PutBucketACL',
// 'name/cos:GetObjectACL',
// 'name/cos:PutObjectACL',
// // 简单 Bucket 操作
// 'name/cos:PutBucket',
// 'name/cos:HeadBucket',
// 'name/cos:GetBucket',
// 'name/cos:DeleteBucket',
// 'name/cos:GetBucketLocation',
// // Versioning
// 'name/cos:PutBucketVersioning',
// 'name/cos:GetBucketVersioning',
// // CORS
// 'name/cos:PutBucketCORS',
// 'name/cos:GetBucketCORS',
// 'name/cos:DeleteBucketCORS',
// // Lifecycle
// 'name/cos:PutBucketLifecycle',
// 'name/cos:GetBucketLifecycle',
// 'name/cos:DeleteBucketLifecycle',
// // Replication
// 'name/cos:PutBucketReplication',
// 'name/cos:GetBucketReplication',
// 'name/cos:DeleteBucketReplication',
// // 删除文件
// 'name/cos:DeleteMultipleObject',
// 'name/cos:DeleteObject',
// 简单文件操作
'name/cos:PutObject',
'name/cos:PostObject',
'name/cos:AppendObject',
'name/cos:GetObject',
'name/cos:HeadObject',
'name/cos:OptionsObject',
'name/cos:PutObjectCopy',
'name/cos:PostObjectRestore',
// 分片上传操作
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload',
'name/cos:AbortMultipartUpload',
),
'effect'=> 'allow',
'principal'=> array('qcs'=> array('*')),
'resource'=> array(
'qcs::cos:' . $config['Region'] . ':uid/' . $AppId . ':prefix//' . $AppId . '/' . $ShortBucketName . '/',
'qcs::cos:' . $config['Region'] . ':uid/' . $AppId . ':prefix//' . $AppId . '/' . $ShortBucketName . '/' . $this->resourceUrlEncode($config['AllowPrefix'])
)
)
)
);
$policyStr = str_replace('\\/', '/', json_encode($policy));
$Action = 'GetFederationToken';
$Nonce = rand(10000, 20000);
$Timestamp = time() - 1;
$Method = 'GET';
$params = array(
'Action'=> $Action,
'Nonce'=> $Nonce,
'Region'=> '',
'SecretId'=> $config['SecretId'],
'Timestamp'=> $Timestamp,
'durationSeconds'=> 7200,
'name'=> 'cos',
'policy'=> urlencode($policyStr)
);
$params['Signature'] = urlencode($this->getSignature($params, $config['SecretKey'], $Method, $config));
$url = $config['Url'] . '?' . $this->json2str($params);
$ch = curl_init($url);
$config['Proxy'] && curl_setopt($ch, CURLOPT_PROXY, $config['Proxy']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
if(curl_errno($ch)) $result = curl_error($ch);
curl_close($ch);
$result = json_decode($result, 1);
if (isset($result['data'])) $result = $result['data'];
return returnSuccessJson($result);
}
// obj 转 query string
public function json2str($obj) {
ksort($obj);
$arr = array();
foreach ($obj as $key => $val) {
array_push($arr, $key . '=' . $val);
}
return join('&', $arr);
}
// 计算临时密钥用的签名
public function getSignature($opt, $key, $method, $config) {
$formatString = $method . $config['Domain'] . '/v2/index.php?' . $this->json2str($opt);
$formatString = urldecode($formatString);
$sign = hash_hmac('sha1', $formatString, $key);
$sign = base64_encode(hex2bin($sign));
return $sign;
}
// 计算临时密钥用的签名
public function resourceUrlEncode($str) {
$str = rawurlencode($str);
//特殊处理字符 !()~
$str = str_replace('%2F', '/', $str);
$str = str_replace('%2A', '*', $str);
$str = str_replace('%21', '!', $str);
$str = str_replace('%28', '(', $str);
$str = str_replace('%29', ')', $str);
$str = str_replace('%7E', '~', $str);
return $str;
}
}