Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable CORS when running AWS SAM CLI locally

Whenever I try to access serverless lambda function via POST through the browser I get the error

Response to preflight request doesn't pass access control check: No >'Access-Control-Allow-Origin' header is present on the requested resource.

When it is a /GET it works fine I have read it is because it is not sending pre flight request. When I change it to POST this is when it fails.

The command I am running:

sam local start-api

And my template.yaml is:

...

Resources:
    PropertiesFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: target/service-0.0.1-SNAPSHOT.jar
            Handler: com.aws.PropertiesHandler::handleRequest
            Runtime: java8
            Events:
                PropertiesApi:
                    Type: Api
                    Properties:
                        Path: /properties
                        Method: post

...

How can I enable CORS on these endpoints?

like image 413
Eduardo Dennis Avatar asked Nov 15 '18 04:11

Eduardo Dennis


People also ask

How does the AWS Sam CLI work with serverless?

When you run this command in a directory that contains your serverless functions and your AWS SAM template, it creates a local HTTP server that hosts all of your functions. By default when you use this command, the AWS SAM CLI assumes that your current working directory is your project's root directory.

Where should I point AWS Sam to build my project?

For more compiled languages or projects that require complex packing support, we recommend that you run your own building solution, and point AWS SAM to the directory or file that contains the build artifacts. To see an end-to-end example that uses this command, see Tutorial: Deploying a Hello World application.

What is Sam in AWS CloudFormation?

SAM or serverless application model is an open-source framework for building serverless applications. It provides shorthand syntax to express functions, APIs, databases, and event source mappings. SAM transforms and expands the SAM syntax into AWS CloudFormation syntax.

How does the AWS Sam CLI find my current working directory?

By default when you use this command, the AWS SAM CLI assumes that your current working directory is your project's root directory. The AWS SAM CLI first tries to locate a template file built using the sam build command, located in the .aws-sam subfolder, and named template.yaml or template.yml.


2 Answers

I had the same error and I have already fixed it in 3 steps. (AWS Lambda in Java8, SAM CLI v0.37.0)

  1. Add options for your header:
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    headers.put("X-Custom-Header", "application/json");
    headers.put("Access-Control-Allow-Origin", "*");
    headers.put("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    headers.put("Access-Control-Allow-Headers", "X-Requested-With,content-type");
  1. Add Option Cors into template.yaml
    Globals:
      Function:
        Timeout: 20
      Api:
        Cors:
          AllowMethods: "'GET,POST,OPTIONS'"
          AllowHeaders: "'content-type'"
          AllowOrigin: "'*'"
          AllowCredentials: "'*'"
  1. Update properties resource function in template.yaml
          Events:
            HelloWorld:
              Type: Api 
              Properties:
                # Path: /hello
                # Method: get
                Path: "/{proxy+}"
                Method: ANY
like image 112
ngoctrambui Avatar answered Sep 19 '22 13:09

ngoctrambui


First, you will need to add the following section in the template.yml to enable cors in the API gateway:

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,OPTIONS'"
      AllowHeaders: "'content-type'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"

Then in your lambda function response


        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", requestContext.getHeaderString("Access-Control-Request-Headers"));
        headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,HEAD,OPTIONS");
like image 31
me2resh Avatar answered Sep 19 '22 13:09

me2resh