亚马逊 S3 设置访问权限与 CORS 跨域完整教程
wxk1991 Lv3

亚马逊 S3 设置访问权限与 CORS 跨域完整教程

很多人在使用:

1
Amazon S3

作为:

  • 图片床
  • 视频存储
  • 静态资源站
  • CDN 源站

时,经常会遇到:

  • 图片无法访问
  • 出现 403 Forbidden
  • 前端跨域报错
  • 视频无法播放
  • 浏览器 CORS 拒绝

这些问题:

1
基本都和 S3 权限配置有关

本篇文章教你:

  • 如何设置 S3 公共访问权限
  • 如何只允许特定网站访问
  • 如何配置 Referer 防盗链
  • 如何设置 CORS 跨域
  • 如何让 Vue / React / Hexo 正常访问 S3 资源

什么是 Amazon S3?

Amazon S3:

1
AWS 的对象存储服务

类似于:

  • 阿里云 OSS
  • 腾讯云 COS
  • Cloudflare R2
  • Backblaze B2

优点:

  • 稳定
  • 全球 CDN
  • API 丰富
  • 支持海量存储
  • 可直接作为静态资源站

很多网站:

1
都会用 S3 存储图片和视频

S3 默认为什么无法访问?

AWS 默认:

1
安全策略非常严格

所以:

1
新建的 Bucket 默认禁止公网访问

如果不配置:

1
访问资源会出现:
1
403 Forbidden

开启公共访问(允许所有网站访问)

适合:

  • 图片床
  • 静态资源站
  • 公共 CDN
  • 视频封面

第一步:进入 Bucket

登录 AWS 后:

进入:

1
S3

找到你的:

1
Bucket(存储桶)

例如:

1
upload-stt

第二步:进入 Permissions(权限)

点击:

1
Permissions

或者:

1
权限

第三步:Bucket Policy(存储桶策略)

找到:

1
Bucket Policy

输入:

1
2
3
4
5
6
7
8
9
10
11
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::upload-stt/*"
}
]
}

配置详解

字段 作用
Allow 允许
Principal: “*” 所有人
s3:GetObject 允许读取文件
upload-stt/* 当前桶下所有文件

效果

配置完成后:

1
任何网站都能访问你的资源

例如:

1
图片
1
JS
1
视频

都能直接打开。


仅允许特定网站访问(防盗链)

很多时候:

1
你不希望别人盗用你的图片

例如:

  • 别的网站直接引用你的图片
  • 偷跑你的流量
  • 消耗你的 CDN 带宽

这时候:

1
可以配置 Referer 防盗链

S3 Referer 防盗链配置

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::upload-stt/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://*.setiantang*.top/*",
"https://*.setiantang*.top/*"
]
}
}
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::upload-stt/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://*.setiantang*.top/*",
"https://*.setiantang*.top/*"
]
}
}
}
]
}

这个配置是什么意思?

作用:

1
仅允许 setiantang.top 域名访问资源

其他网站:

1
全部拒绝

StringLike

表示:

1
允许匹配

StringNotLike

表示:

1
拒绝不匹配的请求

支持子域名

例如:

1
img.setiantang.top
1
www.setiantang.top
1
cdn.setiantang.top

都能访问。


防盗链真的安全吗?

实际上:

1
Referer 可以伪造

所以:

1
它只能防普通盗链

不能防:

  • 高级爬虫
  • 服务端盗链
  • Referer 伪造

但:

1
已经能拦住大部分盗图网站

设置 CORS 跨域

很多前端项目:

  • Vue
  • React
  • Next.js
  • Nuxt
  • Hexo

访问 S3 时:

1
会出现跨域错误

例如:

1
CORS policy blocked

这时候:

1
需要配置 CORS

进入 CORS 配置

进入:

1
Bucket

然后:

1
Permissions

找到:

1
Cross-origin resource sharing (CORS)

推荐 CORS 配置

输入:

1
2
3
4
5
6
7
8
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "POST", "HEAD"],
"AllowedOrigins": ["*"],
"ExposeHeaders": []
}
]

配置详解

配置 作用
AllowedHeaders 允许所有请求头
AllowedMethods 允许的请求方法
AllowedOrigins 允许所有域名
ExposeHeaders 暴露响应头

AllowedMethods 说明

GET

允许:

1
读取资源

例如:

  • 图片
  • 视频
  • CSS
  • JS

POST

允许:

1
上传文件

允许:

1
获取文件头信息

很多播放器会用到。


更安全的 CORS 配置(推荐)

生产环境建议:

1
2
3
4
5
6
7
8
9
10
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedOrigins": [
"https://setiantang.top"
],
"ExposeHeaders": []
}
]

这样:

1
只有你的域名可以跨域访问

更安全。


常见问题

1. 为什么还是 403?

原因可能:

  • Block Public Access 未关闭
  • Bucket Policy 配置错误
  • 文件权限不是 public
  • ARN 写错

2. 为什么图片能打开但前端报跨域?

因为:

1
资源访问 ≠ 允许跨域

需要:

1
单独配置 CORS

3. 为什么视频无法播放?

可能原因:

  • 没开启 HEAD
  • Range 请求被拦截
  • CDN 缓存问题

推荐生产环境方案

推荐:

功能 建议
图片公开访问 开启
防盗链 开启
CORS 仅允许自己域名
CDN CloudFront
HTTPS 开启
缓存 开启 Cache-Control

总结

Amazon S3 常见配置:

功能 配置
公共访问 Bucket Policy
防盗链 aws:Referer
跨域 CORS
静态资源 GET 权限
上传功能 POST 权限

推荐:

1
公共资源 + CDN + Cache-Control + Referer 防盗链

这样:

  • 速度快
  • 更安全
  • 带宽消耗低
  • 更适合生产环境

非常适合:

  • 图片站
  • 视频站
  • Hexo 博客
  • Vue / React 项目
  • CDN 静态资源站