Laravel中为AWS S3预签名URL添加图片格式与大小验证
解决AWS S3预签名URL的图片格式与大小限制问题
你之前的问题核心是错误地将conditions参数直接放在PutObject命令参数中——这个参数属于Post表单上传的策略配置,并不适用于PutObject的预签名请求。要实现你需要的双格式限制和大小校验,以下是两种可行方案:
方案一:PutObject预签名URL(单一格式限制)
如果只需要限制单一图片格式(比如仅JPEG),可以直接在PutObject命令中指定固定的ContentType,客户端上传时必须匹配该值,否则S3会直接拒绝请求。同时添加内容长度范围限制:
// 初始化S3客户端 $client = new S3Client([ 'version' => 'latest', 'region' => 'ap-south-1', ]); $bucket = 'bucket_name'; $key = 'target-image-key'; $maxFileSize = 2 * 1024 * 1024; // 2MB换算为字节 // 创建PutObject命令,指定必须匹配的Content-Type $command = $client->getCommand('PutObject', [ 'Bucket' => $bucket, 'Key' => $key, 'ContentType' => 'image/jpeg', // 固定为JPEG格式 ]); // 添加文件大小范围限制 $command->getHandlerList()->appendBuild(function ($command) use ($maxFileSize) { $command['@http']['headers']['Content-Length'] = ['range' => [0, $maxFileSize]]; }); // 生成有效期20分钟的预签名URL $presignedRequest = $client->createPresignedRequest($command, '+20 minutes'); echo (string) $presignedRequest->getUri();
注意:这种方式无法同时支持JPEG和PNG两种格式,因为PutObject预签名URL是绑定单一请求参数的。如果需要多格式支持,推荐使用方案二。
方案二:PostObject预签名表单(多格式+大小限制)
Post表单上传的方式支持更灵活的条件约束,能同时实现多格式校验和大小限制,上传违规文件时S3会直接返回对应错误:
// 初始化S3客户端 $client = new S3Client([ 'version' => 'latest', 'region' => 'ap-south-1', ]); $bucket = 'bucket_name'; $uploadPathPrefix = 'user-uploaded-images/'; // 可选:限制上传路径前缀 $maxFileSize = 2 * 1024 * 1024; // 2MB $expireTime = '+20 minutes'; // 定义上传规则条件 $conditions = [ ['bucket' => $bucket], // 限制文件必须上传到指定路径前缀下 ['starts-with', '$key', $uploadPathPrefix], // 允许JPEG或PNG两种格式 ['or', ['eq', '$Content-Type', 'image/jpeg'], ['eq', '$Content-Type', 'image/png'] ], // 限制文件大小在0到2MB之间 ['content-length-range', 0, $maxFileSize], // 可选:设置上传文件的ACL为私有 ['acl' => 'private'] ]; // 生成Post上传的签名表单参数 $postFormParams = $client->createPresignedPost([ 'Bucket' => $bucket, 'Conditions' => $conditions, 'Expires' => $expireTime, 'Fields' => [ 'key' => $uploadPathPrefix.'${filename}' // 保留原始文件名,可自定义Key规则 ] ]); // 输出表单参数(前端可直接用这些参数构建上传表单) echo json_encode($postFormParams);
原代码失效原因
conditions是Post上传策略的专属配置项,PutObject命令并不识别该参数,所以你之前的条件配置完全不会被S3处理。只有通过createPresignedPost方法生成的表单上传参数,才能正确应用这些规则约束。
违规上传的错误反馈
当客户端上传违反规则时,S3会返回明确错误:
- 上传非JPEG/PNG格式文件:返回
403 Forbidden,提示签名不匹配 - 文件大小超过2MB:返回
413 Request Entity Too Large
内容的提问来源于stack exchange,提问作者Harshil Patanvadiya
相关产品推荐
相关产品推荐

