Fetch blocked by CORS, it does not have HTTP OK status

0

Background

I have a website hosted on AWS. The architecture is as follows.

Architecture

This has been working for years. Recently I have made a deployment which failed for a reason related to this AWS change: Advanced Notice: Amazon S3 will automatically enable S3 Block Public Access and disable access control lists for all new buckets starting in April 2023

As a result I had to make permissions changes on the S3 bucket that hosted the website. I started to use ACLs, and made sure all website resources have list and read permissions.

I had to wipe off the CloudFront stack (including all resources) and deploy everything from scratch. This could have contributed to the problem I am seeing. It is possible that I may have missed a step, but I am not sure what.

Problem

When the user attempts to login, this makes a POST request with login credentials via js fetch API. Under the covers there is a preflight OPTIONS request which should normally return 200 ok, then the POST request follows that.

However the preflight OPTIONS request now has error 403 Forbidden error. The debugger's console prints an error as follows:

Access to fetch at 'https://api-{domain}/{stage}/authenticate' from origin 'https://{domain}' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Chrome debugger console

The network tab shows OPTIONS status code as 403 to preflight request.

Enter image description here

I noticed this response header too:

X-Amzn-Errortype: MissingAuthenticationTokenException

Investigation

I ran a CORS check on the OPTIONS request, verified that the CORS headers enabled on the API Gateway were present in the response, including Access-Control-Allow-Origin was set to '*'.

On the API Gateway console I verified that OPTIONS method response was set correctly to provide HTTP status: 200.

Enter image description here

I checked the Internet for days hoping to find a similar problem with no avail. I'll appreciate any help provided.

Many thanks in advance.

3 Answers
1

Hi,

Assuming that there's a method and resource configured in the API Gateway resource path, and that you're sending the correct HTTP method request to the REST API endpoint, it could be that the API Gateways authorization settings are also applied to the OPTIONS method, and the request it not including the Authorization header on the CORS pre-flight checks (MissingAuthenticationTokenException).

Could you check and disable it if it was the case? CORS methods are not meant to be authorized. If this is not the case, I recommend you enable the API Gateway execution logs and analyse what is happening.

profile picture
EXPERT
answered 10 months ago
  • Thanks for your response. I've just checked the CloudFormation template, for all endpoints "AuthorizationType": "NONE" was specified. I'll check the logs.. Thanks..

  • I enabled CloudWatch execution logs for API Gateway. I haven't seen the execution log group created yet.. is this normal?

  • Have you granted to the API Gateway permission to read and write logs to CloudWatch for your account?

    On the hand, and as explained to the following Knowledge Center article, not all client-side errors rejected by API Gateway are logged into execution logs. For example, a client making an API request to an incorrect resource path of your REST API returns a 403 "Missing Authentication Token" response. Sorry for the insistence, but are you sure that the path is correct? I'm just trying to get you to rule out options.

  • Additionally, have you use the API Gateway console to check that API method works correctly?

  • I used API Gateway console and successfully tested OPTIONS and POST requests (somehow API GW execution log group was created for the API but there were no streams, but that's a secondary problem.) So looks like the path was not set correctly.

    I figured out what the problem is. In the API mapping for my API's custom domain name I forgot to add stage to path (that's how I designed it years ago, but I forgot.) . I use serverless framework to deploy, which hides API Gateway related configuration. So I must have added mappsing manually using the "Custom domain names" configuration at the time, which I missed today when I recreated the stack. . Mikel Del Tio, you have been very helpful to nail this problem. It was a tough one. Many thanks!

0
Accepted Answer

I figured out what the problem was. In the "Custom domain names" API mappings, I forgot to set stage on the path entity (that's how I designed it years ago.)

I use serverless framework (sls) to deploy. Sls hides API Gateway related configuration. In the working (previous) version of my application I must have added correct mappings manually using the "Custom domain names" configuration at the time. This was the step that I missed when I recreated the stack.

Finally, I should point out that, while I was debugging the issue 403 Forbidden error (and CORS errors) misled me. In hindsight however the api path without the path mapping was still legitimate, albeit not accessible, since the mapping was not including it and the client was requesting it. So 403 made sense.

Many thanks to Mikel Del Tio for useful tips in the right direction and staying with me till the problem was fixed.

Ergun
answered 10 months ago
profile picture
EXPERT
reviewed 10 months ago
0
profile picture
EXPERT
answered 10 months ago
profile picture
EXPERT
reviewed 10 months ago
  • Thanks for your response. I applied a (very generous) CORS config on the S3 bucket. Unfortunately it didn't solved the problem. Besides, I am seeing the web application source in the debugger, which means they are loaded from S3. AllowedHeaders: * , AllowedOrigins: *

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions