亚马逊AWS官方博客
使用 ApiGateway 作为 S3 的反向代理
背景
客户目前在其架构中使用 Nginx 作为反向代理,但希望将其迁移至 AWS 托管服务。他们的主要目标是利用 AWS 的功能来实现更高效的资源管理和更可靠的服务,其中一项需求是确保可以使用自定义域名来访问存储在 AWS S3 中的资源,而不直接暴露 S3 桶的地址给终端用户,这样做可以提高安全性并使管理更加方便;此外,客户还希望在遇到 S3 资源不存在、无法访问或权限问题时,不直接返回标准的 4XX 错误代码,而是返回自定义的状态码,以便在用户界面上提供更加友好和可控的体验。
方案
解决方案
- 使用 AWS 托管服务 API Gateway 给 S3 配置代理,用来转发资源请求
- 使用 API Gateway 配置自定义响应参数
架构图:
涉及 AWS 服务:
- AWS API Gateway
- IAM
- S3
方案特点:
优势:
- 扩展性:AWS API Gateway 可以自动扩展以处理大量的请求流量,无需您担心基础设施扩容。
- 性能:它可以提供低延迟和高性能,确保快速响应客户端请求。
- 安全性:AWS API Gateway 支持身份验证和授权机制,可用于保护您的后端服务。您可以轻松集成 AWS Cognito、AWS IAM 或自定义身份验证方法。
- 监控和分析:它提供了丰富的监控和分析功能,以便您可以实时监视请求、响应时间和错误。
- 缓存:您可以配置缓存策略,以减轻后端服务的负载并提高响应时间。
- 部署和管理:AWS API Gateway 提供了方便的管理工具,允许您轻松配置、部署和更新 API。
劣势:
- 成本:使用 AWS API Gateway 可能会带来一些费用,尤其是在处理大量请求时。您需要根据使用情况来评估成本。
- 复杂性:配置和管理 API Gateway 可能会有一定的复杂性,特别是对于复杂的路由和策略设置。
- 依赖性:将 API Gateway 用作反向代理可能使您的应用程序依赖于 AWS 服务,这可能在将来的迁移或架构变更时引入一些依赖性。
- 限制:AWS API Gateway 有一些限制,包括请求大小、并发连接数等。您需要了解这些限制并确保它们适合您的需求。
限制:
具体实现步骤
配置步骤:
Section 1 – IAM 配置
新建 IAM Role
添加信任策略,可以直接复制以下权限语句,请关注红色字体部分
不添加托管权限(之后会创建内联策略)
命名,检查内容,并且创建
选择刚才创建的 Role
在权限 Tab 中,点选添加权限,选择创建内联策略(内联策略仅针对当前的选择的 Role,一般建议通用权限可以创建客户托管权限)
指定权限,选择 JSON
授予访问 S3 的权限
- 范例一,仅赋予获取 S3 对象的权限
或者
- 范例二,仅赋予获取以及列举 S3 对象或者桶等的权限(本文使用范例二权限)
创建此条策略,多数情况下请在 IAM>策略选项下新建托管策略,托管策略更适合多数情况,比如通用的策略等,本文使用角色下的内联策略作为范例
请记录此角色的 ARN,后续步骤中会使用到此 ARN
Section 2 – API Gateway 创建
打开 AWS API Gateway 控制台
选择 REST API 创建
填写 API 名称,在 API 端点终端类型中选择区域
点击创建,可以看到已经创建完成的 API
在 Root 资源下,即显示“/”的情况下,选择创建方法
在方法类型中选择 GET,集成类型中选择亚马逊云科技服务,在区域中选择您所在的区域(北京区域为 cn-north-1,宁夏区域为 cn-northwest-1),亚马逊云科技服务请选择 S3,HTTP 方法选择 GET
在操作类型中选择“使用路径覆盖”,并且填写目标桶的名称,以及之前创建的角色的 ARN
关于路径覆盖
- 如果填写“/“(仅填写反斜杠,无需引号),则表示 S3 服务根目录
- 如果填写具体桶名称,则指向 S3 桶的根目录,即图示中的配置为将 API 中的 GET request https//your-api-host/stage 指向到您的 S3 桶的 https://your-s3-host/index.html 的路径
本文中直接使用“/“指向 S3 根目录
Section 3 – S3 桶设置与 API Gateway 详细配置
创建公开 Amazon S3 服务功能的 API 资源
- 创建 Folder 资源表示 S3 桶
- 创建 Item 资源表示 S3 桶中对象
公开 API 方法以列出调用方的 Amazon S3 存储桶
- 从 Resources(资源)面板右上角的 Actions(操作)下拉菜单中,在根节点 (/) 上选择 Create method(创建方法)。在 HTTP 动词的下拉列表中选择 GET,然后选择对勾图标以开始创建方法
- 在方法类型中选择 GET,集成类型中选择亚马逊云科技服务
- 在亚马逊与科技区域中填写您的 S3 桶所在区域,服务则选择 S3,HTTP 方法选择 GET,操作类型选择 使用路径覆盖,并且填写“/” 用以表示 S3 服务根目录,复制之前创建的 IAM 角色的 ARN(来自 IAM 控制台),并将其粘贴到执行角色中
使用 IAM 对此 API 进行访问控制
- 在此 GET 方法中,选择方法请求,并点选编辑
- 在授权中,选择 Amazon IAM
添加 GET 方法对响应类型
- 在方法响应中创建响应
- 添加 400 响应
- 重复以上步骤,添加 500 响应
对 GET 方法增加响应标头
- 在方法响应中,选择响应 200,进行编辑
- 添加标头,将 Timestamp, Content-Length,Content-Type 分别添加进标头(注意带小写)
在 GET 方法对集成响应中,增加标头映射
- 编辑响应
- 增加标头映射
- 在 GET 方法对集成响应中,为 500 响应,400 响应分别创建响应,并且添加正则表达式
- 在 GET 方法的测试选项中测试根资源下的 GET 请求
公开 API 方法以访问 Amazon S3 存储桶
- 在 Folder 资源上创建 GET 方法
- 在方法类型中选择 GET,集成类型中选择亚马逊云科技服务
- 在亚马逊与科技区域中填写您的 S3 桶所在区域,服务则选择 S3,HTTP 方法选择 GET,操作类型选择使用路径覆盖,并且填写“{bucket}” 用以表示指定的 S3 桶,复制之前创建的 IAM 角色的 ARN(来自 IAM 控制台),并将其粘贴到执行角色中
- 创建完成
- 在此 GET 方法的方法请求中,进行 URL 查询字符串的编辑,添加 folder 字符串
- 在此 GET 方法的方法请求中,进行 HTTP 请求标头的编辑
- 在 HTTP 请求标头中,添加标头,Content-Type
- 在此 GET 方法的集成请求中,进行 URL 路径参数编辑
- 在 URL 路径参数中添加路径参数,添加名称 bucket,映射自填写 method.request.path.folder
- 在 HTTP 标头中添加标头,添加 Content-Type 标头
Section 4 – S3 桶设置与 API Gateway 详细配置
选择需要使用到的目标 S3 桶,并且选择权限 Tab
在存储桶策略中编辑并且写入以下权限,请将权限 JSON 中的红色文字替换为:
- 目标桶的名字
- API Gateway 中 GET 方法的 ARN
映射模版参考文档:
总结
本文介绍了如何使用 AWS API Gateway 作为 S3 的反向代理,主要目的是允许使用自定义域名访问 S3 中的资源,而不直接暴露 S3 桶地址,从而提高安全性和管理便利性。另外,它还可以在遇到 S3 资源不存在等情况时返回自定义状态码,提升用户体验。
该方案利用了 AWS 托管服务的优势,如自动扩展、高性能、安全性好等,但也需要注意成本、复杂性和 AWS 服务依赖等潜在问题。文档还提供了相关配置细节和参考资料,对于需要类似需求的用户很有参考价值。