Laravel中需分别配置S3和OSS磁盘,OSS必须用阿里官方SDK封装的Flysystem适配器注册自定义驱动,不可复用s3配置;通过Storage::disk('oss')显式调用,注意URL生成、权限策略及环境变量隔离。

如何在 Laravel 中配置多个云存储驱动(S3/OSS)
Laravel 的 Filesystem 支持多磁盘配置,但默认只预设了 s3 驱动;对接阿里云 OSS 需要手动注册自定义驱动,不能直接复用 s3 配置。核心在于:OSS 兼容 S3 协议,但认证方式、Endpoint 规则、签名逻辑有差异,必须用适配过的 SDK 驱动。
- 不要把 OSS 的
endpoint直接填进filesystems.php的s3配置里——Laravel 原生s3驱动会错误拼接 URL,导致 403 或 404 - 推荐使用
league/flysystem-aws-s3-v3+aliyuncs/oss-sdk-php分开管理:S3 用官方驱动,OSS 必须用阿里官方 SDK 封装的 Flysystem 适配器 - 多云场景下,每个磁盘需独立声明驱动类型,不能共用
default磁盘别名
注册 OSS 驱动并配置磁盘
在 App\Providers\AppServiceProvider::boot() 中注册 oss 驱动,依赖 aliyuncs/oss-sdk-php 和 overtrue/flysystem-oss(轻量封装,比手写 Adapter 更稳)。
use Illuminate\Support\Facades\Storage;
use League\Flysystem\Filesystem;
use Overtrue\Flysystem\OssAdapter;
use AlibabaCloud\OSS\OssClient;
public function boot()
{
Storage::extend('oss', function ($app, $config) {
$client = new OssClient(
$config['access_key_id'],
$config['access_key_secret'],
$config['endpoint'],
false // 不自动开启 CNAME
);
return new Filesystem(new OssAdapter($client, $config['bucket'], $config['prefix'] ?? ''));
});
}
然后在 config/filesystems.php 新增磁盘:
'disks' => [
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'), // S3 兼容服务(如 MinIO)才需要
],
'oss' => [
'driver' => 'oss',
'access_key_id' => env('OSS_ACCESS_KEY_ID'),
'access_key_secret' => env('OSS_ACCESS_KEY_SECRET'),
'endpoint' => env('OSS_ENDPOINT'), // 如 'https://oss-cn-hangzhou.aliyuncs.com'
'bucket' => env('OSS_BUCKET'),
'prefix' => env('OSS_PREFIX', ''),
],
]
使用时如何避免跨磁盘误操作
调用 Storage::disk('xxx') 是显式且安全的,但容易踩的坑是:全局辅助函数 storage_path() 只指向本地 storage/app,和磁盘无关;Storage::put() 默认走 default 磁盘,不指定就是 local。
- 上传到 OSS 必须写全:
Storage::disk('oss')->put('images/photo.jpg', $content) - 生成可访问 URL:S3 磁盘用
Storage::disk('s3')->url('path');OSS 磁盘需额外配置url键或重写OssAdapter::getUrl(),否则返回空字符串 - 删除操作不支持跨磁盘通配符,
Storage::deleteDirectory()在 OSS 上实际是逐个delete,注意大目录可能超时
环境变量与敏感信息隔离
多云配置意味着更多密钥字段,.env 里必须严格区分前缀,避免混淆:
AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_BUCKET=my-bucket AWS_DEFAULT_REGION=us-east-1 OSS_ACCESS_KEY_ID=LTAI... OSS_ACCESS_KEY_SECRET=... OSS_BUCKET=my-oss-bucket OSS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
OSS 的 access_key_id 格式以 LTAI 开头,S3 是 AKIA,这个特征可用于部署时做简单校验,防止环境错绑。
真正麻烦的是权限策略粒度:S3 的 IAM Policy 和 OSS 的 RAM Policy 写法完全不同,即使配置对了,也会因最小权限原则导致 403;建议先用主账号密钥验证流程,再逐步收紧权限。










