本教程介绍如何在Web端通过表单上传方式直接上传数据到OSS。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。这种方式需通过应用服务器中转,传输效率明显低于数据直传至OSS的方式。
服务端签名直传是指在服务端生成签名,将签名返回给客户端,然后客户端使用签名上传文件到OSS。由于服务端签名直传无需将访问密钥暴露在前端页面,相比客户端签名直传具有更高的安全性。本文介绍如何进行服务端签名直传。
/**
* @desc 获取上传策略签名
* @param array $param
* @return array
* @author Tinywan(ShaoBo Wan)
*/
public static function getUploadPolicy(array $param): array
{
$param['type'] = 'images';
$config = [
'accessKeyId' = 'xxxxxxxxxxxxxxx',
'accessKeySecret' = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
'callbackUrl' = 'https://oss.tinywan.com/aliyun/oss-upload-callback',
'images' = [
'bucket' = 'images',
'host' = 'https://images.tinywan.com',
'endpoint' = 'oss-cn-hangzhou.aliyuncs.com',
'ContentLengthMin' = 10,
'ContentLengthMax' = 20 * 1024 * 1024,
]
];
$bucket = $config[$param['type']];
// 文件路径和文件名
$dir = self::PROJECT_BUCKET . DIRECTORY_SEPARATOR . env('env_name') . DIRECTORY_SEPARATOR . self::getDirectoryPath($param['type'], $param['dirname']);
$key = $dir . self::getRandomFilename($param['ext']);
// 过期时间
$expiration = self::getExpireTime(self::EXPIRE_TIME);
// 参数设置
$policyParams = [
'expiration' = $expiration,
'conditions' = [
['starts-with', '$key', $dir],
['content-length-range', $bucket['ContentLengthMin'], $bucket['ContentLengthMax']]
]
];
$policyBase64 = self::getPolicyBase64($policyParams);
$signature = self::getSignature($policyBase64, $config['accessKeySecret']);
// 回调
$callbackParam = [
'callbackUrl' = $config['callbackUrl'],
'callbackBody' = 'filename=${object}size=${size}mimeType=${mimeType}height=${imageInfo.height}width=${imageInfo.width}',
'callbackBodyType' = 'application/x-www-form-urlencoded',
];
$callbackString = json_encode($callbackParam);
$base64CallbackBody = base64_encode($callbackString);
return [
'access_id' = $config['accessKeyId'],
'host' = 'https://' . $bucket['bucket'] . '.' . $bucket['endpoint'], // $host的格式为 bucketname.endpoint
'policy' = $policyBase64,
'signature' = $signature,
'expire' = $expiration,
'callback' = $base64CallbackBody,
'dir' = $dir,
'key' = $key,
'url' = $bucket['host'] . DIRECTORY_SEPARATOR . $key
];
}