Search code examples
amazon-web-serviceslambdaaws-api-gatewayserverless

Serverless AWS Lambda CORS Error


I am trying to do an http request from an angularjs app to a lambda function that I had setup using serverless.

Here is my serverless.yaml function

functions:
   createcustomer:
    handler: handler.createcustomer
    events: 
      - http: post /createcustomer
        cors: true

Create Customer Function

module.exports.createcustomer = (event, context, callback) => {

    let customer = JSON.parse(event.body).customer;

    service.create(customer, function(result) {
        let response = {
            statusCode: 200,
            headers: {
                "Access-Control-Allow-Credentials": true,
                "Access-Control-Allow-Origin": "*",
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                result: 'Created Customer Successfully',
                message: 'The account has been created!',
                type: 'success',
                customer: result
            })
        };
        callback(null, response);
    });
};

From my AngularJS app I call it like this

app.factory('MyFactory', ['$http', function($http) {
    return {
        CreateCustomer: function(customer) {$http.post('<apipath>/createcustomer', {customer:customer})}
    }
}]);

However, I keep getting this error:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. The response had HTTP status code 403.

I have tried to enable CORS in the API Gateway on the POST method, but that did not change the outcome.

I've also tried setting CORS in the yaml file explicitly

functions:
   createcustomer:
    handler: handler.createcustomer
    events: 
      - http: post /createcustomer
        cors:
          origin: '*'

Still no luck.

Does anyone know what I'm doing wrong here?

One weird thing is that I could get the post to work just fine through PostMan, but if I try it through my app it breaks.

Thanks

UPDATE

enter image description here

When I do serverless deploy it shows up in AWS like the picture above and the method looks like this

enter image description here

As I said before, I tried to enable CORS directly from the API Gateway console but there was no difference when I tried to call the method.


Solution

  • Your update with screenshots shows that the OPTIONS method is not set up for any of these resources. When you enable CORS for an API Gateway resource in the console, AWS sets this up automatically.

    You can see this happen in the AWS console when you enable CORS for a resource, but, of course, your serverless deploy is overwriting this configuration.

    To have the /createcustomer resource properly configured in AWS by the serverless deploy, you can rewrite this part of your serverless.yaml:

    events: 
      - http: post /createcustomer
        cors: true
    

    To look like this:

    events:
      - http:
          path: /createcustomer
          method: post
          cors: true
    

    I'm not an expert in the framework's .yml syntax, so I can't explain exactly why this is.

    Nonetheless, I've confirmed that a file like this:

    functions:
      deletecustomer:
        handler: handler.deletecustomer
        events:
          - http:
              path: /deletecustomer
              method: post
              cors: true
      createcustomer:
        handler: handler.createcustomer
        events: 
          - http: post /createcustomer
            cors: true
    

    will create two resources in AWS API Gateway, one correctly configured for CORS, and one missing the OPTIONS method:

    Two resources, one correct and one missing OPTIONS