You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CloudFront时无法删除AWS S3存储桶文件的问题排查

Laravel+Filament+Spatie MediaLibrary 结合CloudFront后无法删除S3文件问题

环境配置

  • Laravel 10
  • Filament 3
  • Spatie MediaLibrary(最新版)
  • AWS S3 + CloudFront 内容分发

S3存储桶策略

{"Version": "2012-10-17","Id": "PolicyForCloudFrontPrivateContent","Statement": [{"Sid": "AllowCloudFrontServicePrincipal","Effect": "Allow","Principal": {"Service": "cloudfront.amazonaws.com"},"Action": ["s3:GetObject","s3:DeleteObject"],"Resource": "arn:aws:s3:::xxxxxx.xxx/*","Condition": {"StringEquals": {"AWS:SourceArn": "arn:aws:cloudfront::xxxxx:distribution/xxxxxx"}}}]

Laravel 文件系统配置(config/filesystems.php)

'disks' => [
    'local' => [
        'driver' => 'local',
        'root' => storage_path('app'),
        'throw' => false,
    ],
    'public' => [
        'driver' => 'local',
        'root' => storage_path('app/public'),
        'url' => env('APP_URL') . '/storage',
        'visibility' => 'public',
        'throw' => false,
    ],
    's3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'folder' => env('AWS_FOLDER'),
        'view_url' => env('AWS_VIEW_URL'),
        'url' => env('AWS_S3_CLOUDFRONT'),
        'endpoint' => env('AWS_ENDPOINT'),
        'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
        'throw' => true,
    ],
]

问题描述

未使用CloudFront前,通过SpatieMediaLibraryFileUpload组件更新/删除文件时,文件会正常从S3存储桶中移除;切换到CloudFront分发后,仅能创建文件,无法删除或替换文件。

  • 已确认不是缓存问题:通过AWS控制台以root身份直接查看存储桶,文件确实未被删除
  • Laravel日志无错误记录
  • 数据库中的媒体记录已被删除/更新,但S3存储桶内的文件仍保留

已排查操作:

  • 将存储桶策略中的Principal设置为"*",问题依旧存在

期望行为:使用SpatieMediaLibraryFileUpload组件更新/删除文件时,文件应同步从S3存储桶中移除或更新。


问题排查与解决方案

1. 补全IAM用户的S3操作权限

你的存储桶策略仅允许CloudFront服务主体执行删除操作,但Laravel应用是通过IAM密钥(AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY)直接访问S3的,当前使用的IAM用户/角色需要拥有明确的删除、写入权限:

给该IAM用户添加如下权限策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::xxxxxx.xxx/*"
        }
    ]
}

注:存储桶策略和IAM用户权限是叠加生效的,两者都需要允许对应操作才能执行成功。

2. 确认CloudFront配置不影响S3写入/删除

CloudFront仅负责内容分发,不会直接拦截S3的API操作:

  • 你在filesystems.php中设置的url为CloudFront域名,仅影响文件的前端访问地址,Laravel对S3的删除/更新操作是直接调用S3 API,不走CloudFront
  • 检查CloudFront的Origin Access Control(OAC)或Origin Access Identity(OAI)配置,确保仅限制读取权限,未干扰写入/删除操作

3. 验证Spatie MediaLibrary的磁盘绑定

确认你的媒体模型正确指定了使用s3磁盘:

use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class YourModel extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('your-collection')
             ->useDisk('s3'); // 必须明确指定使用s3磁盘
    }
}

同时确认删除操作触发了MediaLibrary的原生逻辑,比如调用$model->clearMediaCollection()或$mediaItem->delete()。

4. 开启AWS SDK调试日志排查细节

在.env中添加以下配置,开启详细的AWS请求日志:

AWS_DEBUG=true
LOG_CHANNEL=stack
LOG_LEVEL=debug

执行删除操作后,查看storage/logs/laravel.log中的AWS SDK请求记录,可直接定位是否存在API调用失败的具体原因。


内容的提问来源于stack exchange,提问作者Zeli Torres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:02:13