本文目录导读:

在PHP项目中生成临时凭证(直传签名),通常用于阿里云OSS、腾讯云COS或AWS S3等云存储服务的客户端直传场景,以下是几种常见云服务的实现方式:
阿里云OSS 直传签名
使用STS临时凭证(推荐)
<?php
use OSS\OssClient;
use OSS\Core\OssException;
require_once 'vendor/autoload.php';
// 配置
$accessKeyId = 'your-access-key-id';
$accessKeySecret = 'your-access-key-secret';
$roleArn = 'acs:ram::123456789:role/oss-upload-role'; // RAM角色ARN
$bucket = 'your-bucket';
$region = 'oss-cn-hangzhou';
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, "https://sts.{$region}.aliyuncs.com");
// 申请临时凭证
$response = $ossClient->assumeRole($roleArn, 'session-name-'.time(), 3600);
$tempCredentials = [
'accessKeyId' => $response['Credentials']['AccessKeyId'],
'accessKeySecret' => $response['Credentials']['AccessKeySecret'],
'securityToken' => $response['Credentials']['SecurityToken'],
'expiration' => $response['Credentials']['Expiration'],
'region' => $region,
'bucket' => $bucket
];
echo json_encode($tempCredentials);
} catch (OssException $e) {
echo json_encode(['error' => $e->getMessage()]);
}
简单上传签名(不使用STS)
<?php
function getOssUploadSignature($bucket, $object, $expiration = 3600) {
$accessKeyId = 'your-access-key-id';
$accessKeySecret = 'your-access-key-secret';
$region = 'oss-cn-hangzhou';
$host = "{$bucket}.{$region}.aliyuncs.com";
$expireTime = time() + $expiration;
$expirationGmt = gmdate('Y-m-d\TH:i:s\Z', $expireTime);
$policy = [
'expiration' => $expirationGmt,
'conditions' => [
['bucket' => $bucket],
['eq', '$key', $object],
['content-length-range', 0, 1048576000]
]
];
$policyJson = json_encode($policy);
$policyBase64 = base64_encode($policyJson);
$signature = base64_encode(hash_hmac('sha1', $policyBase64, $accessKeySecret, true));
return [
'accessid' => $accessKeyId,
'host' => "https://{$host}",
'policy' => $policyBase64,
'signature' => $signature,
'expire' => $expireTime,
'key' => $object,
'callback' => '' // 可选:回调URL
];
}
腾讯云COS 直传签名
使用临时密钥(推荐)
<?php
require_once 'vendor/autoload.php';
use Qcloud\Cos\Client;
$secretId = 'your-secret-id';
$secretKey = 'your-secret-key';
$region = 'ap-guangzhou';
$bucket = 'example-1250000000';
// 获取临时密钥
try {
$cosClient = new Client([
'region' => $region,
'schema' => 'https',
'credentials' => [
'secretId' => $secretId,
'secretKey' => $secretKey
]
]);
// 申请临时密钥(需额外安装Qcloud/Cos模块)
$result = $cosClient->getObjectUrl($bucket, 'test.txt', '+1 hour');
// 或者手动生成临时密钥
$tempKeys = [
'TmpSecretId' => 'your-temp-secret-id',
'TmpSecretKey' => 'your-temp-secret-key',
'Token' => 'your-temp-token',
'ExpiredTime' => time() + 3600,
'StartTime' => time(),
'Region' => $region,
'Bucket' => $bucket
];
echo json_encode($tempKeys);
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
简单上传签名
<?php
function getCosUploadSignature($bucket, $region, $expiration = 3600) {
$secretId = 'your-secret-id';
$secretKey = 'your-secret-key';
$currentTime = time();
$keyTime = "{$currentTime};{$currentTime}+{$expiration}";
$signKey = hash_hmac('sha1', $keyTime, $secretKey);
// 构建签名
$httpMethod = 'post';
$uri = '/';
$headers = "host={$bucket}.cos.{$region}.myqcloud.com";
$params = '';
$stringToSign = "{$httpMethod}\n{$uri}\n{$params}\n{$headers}\n";
$signature = hash_hmac('sha1', $stringToSign, $signKey);
return [
'secretId' => $secretId,
'signature' => $signature,
'keyTime' => $keyTime,
'bucket' => $bucket,
'region' => $region
];
}
AWS S3 直传签名
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Credentials\Credentials;
// 配置
$region = 'us-east-1';
$bucket = 'your-bucket';
$awsKey = 'your-aws-access-key';
$awsSecret = 'your-aws-secret-key';
// 创建S3客户端
$s3Client = new S3Client([
'version' => 'latest',
'region' => $region,
'credentials' => new Credentials($awsKey, $awsSecret)
]);
// 生成预签名上传URL
try {
$command = $s3Client->getCommand('PutObject', [
'Bucket' => $bucket,
'Key' => 'uploads/' . uniqid() . '.jpg',
'ACL' => 'public-read',
'ContentType' => 'image/jpeg'
]);
$presignedUrl = $s3Client->createPresignedRequest($command, '+1 hour');
$url = (string) $presignedUrl->getUri();
echo json_encode(['uploadUrl' => $url]);
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
通用直传签名(自建服务)
<?php
class DirectUploadSigner {
private $secretKey;
public function __construct($secretKey) {
$this->secretKey = $secretKey;
}
public function generateSignedUrl($bucket, $object, $expiration = 3600) {
$expireTime = time() + $expiration;
$data = "{$bucket}|{$object}|{$expireTime}";
$signature = hash_hmac('sha256', $data, $this->secretKey);
return [
'url' => "https://your-storage.com/{$bucket}/{$object}",
'expires' => $expireTime,
'signature' => $signature,
'key' => $object,
'token' => base64_encode("{$signature}:{$expireTime}:{$bucket}:{$object}")
];
}
public function verifySignedToken($token) {
$decoded = base64_decode($token);
$parts = explode(':', $decoded);
if (count($parts) !== 4) {
return false;
}
list($signature, $expireTime, $bucket, $object) = $parts;
// 检查是否过期
if (time() > $expireTime) {
return false;
}
// 验证签名
$data = "{$bucket}|{$object}|{$expireTime}";
$expectedSignature = hash_hmac('sha256', $data, $this->secretKey);
return hash_equals($expectedSignature, $signature);
}
}
// 使用示例
$signer = new DirectUploadSigner('your-secret-key-here');
$signedData = $signer->generateSignedUrl('my-bucket', 'photos/avatar.jpg', 3600);
echo json_encode($signedData);
最佳实践建议
-
安全考虑:
- 永远不要在客户端暴露长期密钥
- 使用STS/RAM角色获取临时凭证
- 设置合理的过期时间(通常15分钟-1小时)
- 限制上传文件类型和大小
-
性能优化:
- 缓存临时凭证到会话或内存
- 预生成多个签名减少请求
-
错误处理:
- 添加重试机制
- 完善的日志记录
- 前端签名验证
-
权限控制:
- 最小权限原则
- 每个用户/请求独立签名
- 后端验证上传完成的文件
选择哪种方案取决于你的云服务提供商和具体需求,推荐使用云服务商的STS临时凭证方案,安全性更高。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播