Seth Brock
Seth Brock

Reputation: 65

Setting up CORS with Lambda API Gateway CDK

I am trying to set up my API Gateway in AWS through the CDK. I have it set up, but no matter what I try I can't get around CORS to execute the lambda function which reads the database. I'm using C# to write this. Here is the code:

using Constructs;
using Amazon.CDK.AWS.APIGateway;
using Amazon.CDK.AWS.Lambda;
using System.Collections.Generic;

/**
 * This stack creates an API Gateway REST API.
 * The API has a single resource, /items, which supports GET, POST, and PUT methods.
 * Each method is integrated with a Lambda function.
 */

namespace Cdk
{
    public class ApiGatewayStack
    {
        // Need to use RestApiBase instead of RestApi for v1
        public RestApiBase Api { get; }

        public ApiGatewayStack(Construct scope, Function lambdaFunction)
        {
            Api = new RestApi(scope, "ServerlessProjApi", new RestApiProps
            {
                DefaultCorsPreflightOptions = new CorsOptions
                {
                    AllowOrigins = Cors.ALL_ORIGINS,           // Allow all origins
                    AllowMethods = Cors.ALL_METHODS,           // Allow all methods (GET, POST, PUT, etc.)
                    AllowHeaders = new[] { "Content-Type", "X-Amz-Date", "Authorization", "X-Api-Key" } // CORS headers
                }
            });

            SetupApiGateway(Api, lambdaFunction);
        }

        private void SetupApiGateway(RestApiBase api, Function lambdaFunction)
        {
            var lambdaIntegration = new LambdaIntegration(lambdaFunction);
            var options = new MethodOptions
            {
                AuthorizationType = AuthorizationType.NONE,
                MethodResponses = new[] {
                    new MethodResponse
                    {
                        StatusCode = "200",
                        ResponseParameters = new Dictionary<string, bool>
                        {
                            { "method.response.header.Access-Control-Allow-Origin", true },
                            { "method.response.header.Access-Control-Allow-Headers", true },
                            { "method.response.header.Access-Control-Allow-Methods", true }
                        }
                    }
                }
            };

            // Create /items resource
            var items = api.Root.AddResource("items");

            // Add methods for /items resource (GET, POST, PUT)
            items.AddMethod("GET", lambdaIntegration, options);  // GET /items
            items.AddMethod("POST", lambdaIntegration, options); // POST /items
            items.AddMethod("PUT", lambdaIntegration, options);  // PUT /items
        }
    }
}

I first tried the RestApi class, but saw this solution, though the change didn't make a difference. I can access the API through my browser by typing in the endpoint, but not through a webpage. Here is my exact error:

Access to XMLHttpRequest at 'https://{apicode}.execute-api.us-east-1.amazonaws.com/prod/items' from origin 'http://{my-s3-bucket}.s3-website-us-east-1.amazonaws.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Any help is appreciated!

Upvotes: 0

Views: 19

Answers (1)

swawge
swawge

Reputation: 73

The issue might be that while you've configured the CORS preflight, the actual integration responses also need to include CORS headers.

Also, make sure your Lambda function is returning responses that have

Headers = new Dictionary<string, string>
{
    { "Content-Type", "application/json" },
    { "Access-Control-Allow-Origin", "*" }
}

Upvotes: 1

Related Questions