Back to Blog
Lesson 21 of the AWS: AWS Core Services for Developers course
Cloud NativeJuly 28, 20264 min read

Configuring CORS for Web Apps: A Practical AWS Guide

Learn how to configure CORS in AWS API Gateway to allow your web frontend to communicate with your backend. Solve common cross-origin block errors today.

AWSAPI GatewayCORSWeb DevelopmentServerlessCloud Native
Macro photography of color palette code in a programming environment.

Previously in this course, we covered API Gateway Routing and Integration: A Beginner’s Guide to map HTTP paths to Lambda functions. Now that our backend is responding, we often hit a wall: the browser refuses to let our frontend talk to the API. This is where Cross-Origin Resource Sharing (CORS) comes in.

Understanding CORS from First Principles

Browsers implement a security feature called the Same-Origin Policy. This prevents a malicious website from making unauthorized requests to a different domain on your behalf (like stealing your banking session).

An "origin" is defined by the protocol, domain, and port. If your frontend is hosted at https://myapp.com and your API is at https://api.myapp.com, they are different origins. When your JavaScript code sends an XMLHttpRequest or fetch() request, the browser checks if the server explicitly allows the request from that specific origin. If the server doesn't send the correct headers, the browser blocks the response.

CORS is the mechanism that tells the browser, "It is safe to let this domain talk to me."

How CORS Works in API Gateway

When a browser makes a "non-simple" request (like a POST or any request with custom headers), it first sends an OPTIONS request—known as a "preflight" request. The browser asks the server: "Are you okay with this origin, and can I use these methods?"

If your API Gateway isn't configured to handle this OPTIONS request, the browser stops the actual GET or POST call before it even starts.

Configuring CORS in the Console

To enable CORS for your project, follow these steps in your existing API Gateway:

  1. Select your Resource: In the API Gateway console, navigate to the specific resource (e.g., /items) or the root / path.
  2. Enable CORS: Click the Actions button and select Enable CORS.
  3. Define Allowed Origins: In the setup screen, specify your frontend origin (e.g., https://myapp.com or * for testing).
  4. Set Methods and Headers: Ensure GET, POST, and OPTIONS are checked, and that the necessary headers are included.
  5. Deploy: Click Enable CORS and replace existing CORS headers. This will create the OPTIONS method automatically. You must Deploy the API again for these changes to take effect.

Worked Example: Handling the Preflight

When you enable CORS via the console, API Gateway creates an OPTIONS method that returns the following headers:

  • Access-Control-Allow-Origin: Specifies which domains can access the resource.
  • Access-Control-Allow-Methods: Lists allowed HTTP verbs.
  • Access-Control-Allow-Headers: Lists the headers the browser is allowed to send.

If you are using the AWS CDK to manage your infrastructure, you can enable this programmatically:

TYPESCRIPT
const api = new apigateway.RestApi(this, CE9178">'MyApi');
const resource = api.root.addResource(CE9178">'items');

resource.addCorsPreflight({
  allowOrigins: [CE9178">'https://myapp.com'],
  allowMethods: [CE9178">'GET', CE9178">'POST', CE9178">'OPTIONS'],
});

This snippet does the heavy lifting for you, ensuring the OPTIONS response is handled correctly by the gateway without manual console clicking.

Hands-on Exercise

  1. Open your API Gateway console and navigate to the API you built in the previous lesson.
  2. Attempt to fetch() data from your API URL using a browser console from a different origin (or a local localhost file). You should see a "CORS policy" error in the Network tab.
  3. Use the Enable CORS action in the API Gateway console as described above.
  4. Redeploy your API to a stage.
  5. Retry your fetch() call. The error should vanish, and you should see a successful 200 OK response.

Common Pitfalls

  • Forgetting to Deploy: A common mistake is configuring CORS but forgetting to redeploy the API. Changes to integration headers in API Gateway are not live until you deploy the API to a stage.
  • Wildcarding in Production: Using Access-Control-Allow-Origin: * is fine for development, but it prevents you from using credentials (like cookies or Authorization headers). Always specify your actual domain in production.
  • Missing Headers: If your frontend sends a custom header like X-Requested-With, you must ensure it is included in the Access-Control-Allow-Headers list, or the browser will reject the request.

Frequently Asked Questions

Q: Do I need to enable CORS for every single resource? A: It is best practice to enable it on the resources that need it. Enabling it globally on the root / can sometimes lead to conflicts if your architecture is complex.

Q: Why does my browser show a 403 error even with CORS enabled? A: CORS is a browser-level security feature, not a server-level authentication feature. If you get a 403, it usually means your API Gateway's internal resource policy or Lambda authorizer is rejecting the request, not the CORS configuration.

Q: Can I use * for my origin? A: Yes, but only if your requests do not require cookies or HTTP Authentication headers.

Recap

CORS is the bridge between your secure browser environment and your backend. By configuring the OPTIONS preflight request in API Gateway, you allow the browser to verify that your frontend is a trusted origin. Always remember to redeploy your API after making these configuration changes.

Up next: Securing APIs with API Keys.

Similar Posts