服务器迁移后Laravel + S3出现401 Unauthorized错误求助
Hey,我之前处理过好几起服务器迁移后S3鉴权失败的案例,结合你用Laravel 12、Forge、Cloudflare加S3的场景,给你列几个最可能的排查方向,一步步来应该能定位问题:
优先检查环境变量的同步与生效:服务器迁移最容易踩的坑就是环境变量没同步全或者没生效。你可以在新服务器上跑
php artisan env,把输出的S3相关变量(AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_DEFAULT_REGION、AWS_BUCKET)和旧服务器的逐一比对,重点看有没有拼写错误、多余空格(比如密钥末尾不小心带了空格)。另外Forge的环境变量修改后,记得重启PHP-FPM或者整个服务器,不然新的变量可能没加载进去。排查Cloudflare的中间层影响:如果你的请求是通过Cloudflare代理到S3的,先检查这两点:
- SSL模式:Cloudflare的SSL模式要和S3 bucket的证书配置匹配,比如bucket用了自定义域名+SSL,Cloudflare就设为「Full」或「Full (strict)」,避免证书不匹配导致鉴权请求被拦截。
- 缓存干扰:临时开启Cloudflare的「开发模式」(绕过缓存),看看401会不会消失——有时候旧的缓存响应会带错误的鉴权状态。
确认S3的地域与权限配置:
- 地域一致性:Laravel的S3客户端对地域要求很严,如果环境变量里的
AWS_DEFAULT_REGION和bucket实际所在地域不匹配,大概率会触发401,比如bucket在eu-west-1但你设成了us-east-1,一定要核对准确。 - IAM权限:如果用的是IAM密钥对,检查对应的IAM用户有没有被授予该bucket的读写权限(比如
s3:GetObject、s3:PutObject等);如果是服务器用IAM角色关联,要确认新服务器的实例有没有正确绑定有权限的IAM角色。
- 地域一致性:Laravel的S3客户端对地域要求很严,如果环境变量里的
清除Laravel的配置缓存:迁移后旧的配置缓存可能还存着旧服务器的S3配置,跑这几个命令清一下:
php artisan config:clear php artisan cache:clear如果平时用配置缓存的话,清完再重新生成
php artisan config:cache试试。验证S3桶策略与CORS的兼容性:你已经配了CORS,但要确保桶策略没有和CORS冲突——比如桶策略有没有允许你当前的访问来源,CORS配置里有没有设置
Access-Control-Allow-Credentials: true(如果你的请求带了凭据的话)。用AWS CLI做底层测试:在新服务器上装AWS CLI,配置好你的S3密钥后,跑
aws s3 ls s3://你的桶名,如果CLI能成功访问,那问题肯定在Laravel的配置层;如果CLI也报401,那就是AWS密钥或权限的问题,和Laravel无关,直接去AWS控制台排查就行。
内容来源于stack exchange

