简体   繁体   English

如何使用包含多个来源的 AWS Cloudfront 处理 403 和 404 错误

[英]How to handle 403 and 404 errors with AWS Cloudfront containing multiple origins

I have the current configuration in AWS:我在 AWS 中有当前配置:

  1. S3 Bucket set to static website for my frontend S3 存储桶设置为我的前端的 static 网站

  2. ELB which has an EC2 instance for my backend ELB,我的后端有一个 EC2 实例

  3. Cloudfront distribution with two origins, two behaviors, and two custom error pages具有两个来源、两种行为和两个自定义错误页面的 Cloudfront 分发

    • Origins:起源:
      • S3 Bucket (static website) S3 存储桶(静态网站)
      • dev-api.mydomain.com (ALIAS record mentioned below that points to ELB) dev-api.mydomain.com(下面提到的指向ELB的别名记录)
    • Behaviors:行为:
      • "/api/*" routes to dev-api.mydomain.com "/api/*" 路由到 dev-api.mydomain.com
      • "*" routes to S3 “*”路由到 S3
    • Error pages (this part is the most important to my question):错误页面(这部分对我的问题最重要):
      • 403 returns 200 response with index.html (which comes from S3) 403 返回带有 index.html 的 200 响应(来自 S3)
      • 404 returns 200 response with index.html (which comes from S3) 404 返回带有 index.html 的 200 响应(来自 S3)
  4. Route53: 53 号公路:

    • registered domain注册域名
    • dev.mydomain.com points to cloudfront distribution dev.mydomain.com 指向云端分发
    • dev-api.mydomain.com points to ELB dev-api.mydomain.com 指向 ELB

How do I distinguish between the 403 and 404 errors that come back from my S3 and backend server?如何区分从 S3 和后端服务器返回的 403 和 404 错误?

Note: I am using react router to handle all routing in the static website so every request to S3 would return a 404 from S3 unless the user specifically asked for the /index.html resource.注意:我正在使用 react 路由器来处理 static 网站中的所有路由,因此对 S3 的每个请求都会从 S3 返回 404,除非用户特别要求 /index.html 资源。

Scenario 1 : When a user goes to dev.mydomain.com/logi (mispelled login), I would expect that to hit my S3 bucket and return with a 404 which would then fetch the index.html file in the bucket.场景 1 :当用户访问 dev.mydomain.com/logi(拼写错误的登录)时,我希望它会命中我的 S3 存储桶并返回 404,然后它将获取存储桶中的 index.html 文件。 Cloudfront would return the index.html file with a 200 OK Status and my application would handle the invalid route by displaying a 404 page. Cloudfront 将返回 index.html 文件,状态为 200 OK,我的应用程序将通过显示 404 页面来处理无效路由。

Scenario 2 : When a user goes to dev.mydomain.com/login, it would hit my S3 bucket, return with a 404 and return the index.html file.场景 2 :当用户访问 dev.mydomain.com/login 时,它会访问我的 S3 存储桶,返回 404 并返回 index.html 文件。 Once I land on the login page, for this examples sake, I fire off a network request to dev.mydomain.com/api/non_existant_route.一旦我登陆登录页面,为了这个例子,我会向 dev.mydomain.com/api/non_existant_route 发起一个网络请求。 I would expect that to hit my API server and return with a 404 which my frontend would then handle by displaying an error message about the API request failing.我希望它会访问我的 API 服务器并返回 404,然后我的前端将通过显示有关 API 请求失败的错误消息来处理该错误消息。

However what is happening in Scenario 2 is that a 404 is returned from my backend server to Cloudfront, which then returns the index.html file (from S3) as the response with a 200 status code.然而,在场景 2 中发生的情况是 404 从我的后端服务器返回到 Cloudfront,然后返回 index.html 文件(来自 S3)作为带有 200 状态代码的响应。

So, my question is - Is it possible to configure Cloudfront to return different error pages based on the origin that is sending back the error code?所以,我的问题是 - 是否可以将 Cloudfront 配置为根据发回错误代码的来源返回不同的错误页面? If not, how can I accomplish returning the correct response for the backend server?如果没有,我怎样才能完成为后端服务器返回正确的响应?

Would it require me to re-architect my AWS solution?是否需要我重新设计我的 AWS 解决方案?

Another way is to:另一种方法是:

  • turn on Static Web Hosting on S3在 S3 上打开 Static Web 托管
  • replace the S3 bucket name in CloudFront origin with the S3 Static Website URL.将 CloudFront 源中的 S3 存储桶名称替换为 S3 Static 网站 URL。
  • remove Error Pages from CloudFront.从 CloudFront 中删除错误页面。

The error pages will be handled by the respective origins instead of CloudFront.错误页面将由各自的来源而不是 CloudFront 处理。

I was able to solve the 403 and 404 issues by removing Custom Error responses from cloudfront.通过从云端删除自定义错误响应,我能够解决 403 和 404 问题。

I created a Lambda@Edge function on the default behavior (*) which routes to my S3 bucket.我在路由到我的 S3 存储桶的默认行为 (*) 上创建了 Lambda@Edge function。 On Origin Request, the function modifies requests to pages like /login to instead return /index.html from the bucket.在 Origin Request 中,function 修改对 /login 等页面的请求,改为从存储桶返回 /index.html。

In my case, I also have two origins and both are one page app (OPA) so both contains index.js就我而言,我也有两个来源,都是一页应用程序 (OPA),所以都包含index.js

  1. React App (Responsible for my main application) hosted through S3 static website. React App(负责我的主要应用程序)通过 S3 static 网站托管。 (CSR build) (企业社会责任建设)
  2. Webflow App (Static website for product info and blog, etc..) Webflow App(产品信息和博客等的静态网站)

Our react app has many different behaviours based on routes (application need), so I configured Webflow as default behaviour.我们的 React 应用程序根据路由(应用程序需要)有许多不同的行为,所以我将 Webflow 配置为默认行为。

First, I added custom error handling for 404 with redirect page path to /index.js and HTTP Status 200 , as many app routes are not directly present in S3 Website and result into 404 (This is suggested by many tech blog and works very well in case of single origin)首先,我为404添加了自定义错误处理,将页面路径重定向到/index.js和 HTTP 状态200 ,因为许多应用程序路由不直接存在于S3 Website中并导致 404 (许多技术博客都建议这样做并且效果很好如果是单一来源)

But as soon as I added Webflow website origin as my Default(*) behaviour, whenever 404 occurs in React app it will get redirected to default behaviours /index.js (Our static product info website)但是,一旦我将 Webflow 网站来源添加为我的Default(*)行为,每当 React 应用程序中出现404时,它将被重定向到默认行为/index.js (我们的 static 产品信息网站)

Finally, I removed all custom error handling and it will start working as expected.最后,我删除了所有自定义错误处理,它将按预期开始工作。 All the React routes are redirecting to React behaviours and not matching behaviour routes are going to Default(*) Webflow website.所有 React 路由都重定向到 React 行为,而不匹配的行为路由将转到Default(*) Webflow 网站。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM