必须安装对应 flysystem 适配器(如 overtrue/flysystem-oss 或 overtrue/flysystem-cos),正确配置 aws_use_path_style_endpoint=true、完整 region(如 oss-cn-hangzhou)、带协议的 endpoint(如 https://oss-cn-hangzhou.aliyuncs.com),并清空配置缓存;否则即使密钥正确也会因签名或 endpoint 格式不匹配报错。

要在 Laravel 项目中稳定对接阿里云 OSS 或腾讯云 COS,必须绕过 Laravel 原生 S3 驱动的默认假设——它只严格适配 AWS 接口,而 OSS/COS 虽标称“S3 兼容”,实则在 endpoint 构建方式、region 命名规范和协议要求上存在硬性差异;填错任意一项,就会卡在 InvalidAccessKeyId 或 SignatureDoesNotMatch 错误里,密钥本身未必有问题。
配置阿里云 OSS 磁盘
第一步:安装 AWS SDK(Laravel S3 驱动底层依赖)→ composer require aws/aws-sdk-php
第二步:在 .env 中写入真实凭证与完整 endpoint:
AWS_ACCESS_KEY_ID=your_oss_access_key_id
AWS_SECRET_ACCESS_KEY=your_oss_secret_key
AWS_DEFAULT_REGION=oss-cn-hangzhou
AWS_BUCKET=your-bucket-name
AWS_ENDPOINT=https://oss-cn-hangzhou.aliyuncs.com
AWS_USE_PATH_STYLE_ENDPOINT=true
【AWS_DEFAULT_REGION 必须填 oss-cn-hangzhou 这类完整命名,填 cn-hangzhou 直接失败】
第三步:修改 config/filesystems.php 的 s3 磁盘配置,确保 key、secret、region、bucket、endpoint 全部从 env 读取,且显式启用 path-style:
's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => true, ]
这一步不能省略 use_path_style_endpoint → Laravel 默认用子域名格式(bucket.endpoint),OSS 只接受路径格式(endpoint/bucket)。
配置腾讯云 COS 磁盘(推荐独立磁盘)
方法一:复用 s3 驱动但单独定义 cos 磁盘(更安全,避免与 OSS 冲突)
① 在 .env 中新增 COS 专用配置:
COS_APP_ID=1250000000
COS_SECRET_ID=your_cos_secret_id
COS_SECRET_KEY=your_cos_secret_key
COS_REGION=ap-guangzhou
COS_BUCKET=edu-123456789
COS_ENDPOINT=https://cos.ap-guangzhou.myqcloud.com
② 安装腾讯云官方 SDK:composer require tencentcloud/tencentcloud-sdk-php
③ 在 config/filesystems.php 底部新增 cos 磁盘:
'cos' => [ 'driver' => 'cos', 'app_id' => env('COS_APP_ID'), 'secret_id' => env('COS_SECRET_ID'), 'secret_key' => env('COS_SECRET_KEY'), 'region' => env('COS_REGION'), 'bucket' => env('COS_BUCKET'), 'endpoint' => env('COS_ENDPOINT'), 'timeout' => 60, 'connect_timeout' => 60, ]
注意:这个 cos 驱动不是 Laravel 自带的,需额外安装 overtrue/flysystem-cos 才能识别 —— 运行 composer require overtrue/flysystem-cos 后,Laravel 才会把 'cos' 当作合法驱动名。
上传文件到指定云存储磁盘
直接调用 Storage 门面,传入磁盘名即可:
Storage::disk('s3')->put('avatars/123.jpg', file_get_contents($request->file('avatar')));
Storage::disk('cos')->put('logs/app.log', $logContent);
store() 方法更常用,它自动处理临时文件并生成唯一文件名:
$path = $request->file('photo')->store('uploads', 'cos');
返回值是相对路径(如 uploads/abc123.jpg),可直接存数据库。不要用 put() 写死路径,否则覆盖风险高。
【上传前务必确认磁盘已正确加载:dd(Storage::disk('cos')->getAdapter()); 若报错 Adapter not found,说明 overtrue/flysystem-cos 未生效或配置键名不匹配】
生成可访问的文件 URL
OSS 和 COS 都支持私有桶 + 临时签名 URL,但生产环境建议设为公有读,用自定义域名加速:
在 config/filesystems.php 的对应磁盘配置里加 'url' 项:
'url' => 'https://cdn.yourdomain.com'
然后调用:Storage::disk('s3')->url('avatars/123.jpg') → 返回 https://cdn.yourdomain.com/avatars/123.jpg
若没配自定义域名,Laravel 会尝试拼 AWS 格式 URL(如 https://your-bucket.s3.oss-cn-hangzhou.aliyuncs.com),这在 OSS/COS 上不可用,必须手动指定 url 或用临时签名。











