New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I enable CORS? #1955

Closed
Jorenm opened this Issue Aug 24, 2016 · 55 comments

Comments

Projects
None yet
@Jorenm

Jorenm commented Aug 24, 2016

Serverless Framework Version: 1.0.0-beta.1.1

How do I enable CORS so I can access my functions? I can't find anything in the docs, and the CORS plugin seems to not be relevant to the current version of Serverless.

@Jorenm

This comment has been minimized.

Jorenm commented Aug 24, 2016

Digging through the docs I finally managed to find this: https://github.com/serverless/serverless/tree/master/lib/plugins/aws/deploy/compile/events/apiGateway

Sadly, it does not work. For GET requests it seems fine, but for POST it doesn't work.

@ac360

This comment has been minimized.

Member

ac360 commented Aug 25, 2016

Hi all. We are restructuring our docs to make this easier to find.

@Jorenm could you please post more info on your issue so we can verify the error is on our end?

@Jorenm

This comment has been minimized.

Jorenm commented Aug 25, 2016

Here is my serverless.yml config for it:

functions:
  createUser:
    handler: handler.createUser
    events:
      - http:
          path: user/create
          method: post
          cors: true
  getUser:
    handler: handler.getUser
    events:
      - http:
          path: user/load
          method: get
          cors: true

I can confirm when I go to the API Gateway that it is setting up OPTIONS functions, and configuring both end points with the same CORS-related settings.

I'm trying to access them like this:

$.ajax({
    url: 'https://rq6odooeo8.execute-api.us-west-2.amazonaws.com/dev/user/load',
    method: 'get',
    crossDomain: true,
    data: {id: clientId}
}).done(function(response) {
    console.log(response);
});

$.ajax({
    url: 'https://rq6odooeo8.execute-api.us-west-2.amazonaws.com/dev/user/create',
    method: 'post',
    crossDomain: true,
    data: {id: clientId}
}).done(function(response) {
    console.log(response);
});

The GET one works, the POST one throws this error:

XMLHttpRequest cannot load https://rq6odooeo8.execute-api.us-west-2.amazonaws.com/dev/user/create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5200' is therefore not allowed access. The response had HTTP status code 400.

If you'd like details about any of the API Gateway settings, let me know.

@ac360

This comment has been minimized.

Member

ac360 commented Aug 25, 2016

@Jorenm Can you confirm you are adding this header and it's still not working? I just tested your endpoint (sorry) with that Header and it works.

Content-Type: application/json
@Jorenm

This comment has been minimized.

Jorenm commented Aug 25, 2016

I just tested your endpoint (sorry)

Heh, no problem. If I minded I'd have edited it out :P

Content-Type: application/json

Adding this did indeed fix it. I haven't done any CORS stuff before, so maybe this is obvious to most people. If it isn't obvious, putting a sample AJAX request in the CORS section might be good?

Thanks for your help!

@Jorenm Jorenm closed this Aug 25, 2016

@ac360

This comment has been minimized.

Member

ac360 commented Aug 25, 2016

@Jorenm Thanks. I think the issue is we need to have better docs. People run into this problem w/ Angular too.

Let us know how else we can help. We're here full-time and we have LOTS coming :)

@pmuens

This comment has been minimized.

Member

pmuens commented Aug 25, 2016

We're just discussing the new docs structure here. @Jorenm Would be great if you could give some feedback on that #1957

@lakinducker

This comment has been minimized.

lakinducker commented Dec 10, 2016

Hi Serverless Team,

I really like serverless! I was able to quickly get a couple of API's running. I, unfortunately, am having a CORS problem with the API's and Angular 2.

XMLHttpRequest cannot load https://s7t6o3hx8l.execute-api.us-east-1.amazonaws.com/dev/notes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

I using the { 'Content-Type': 'application/json' } in the header for my GET from Angular. Also I know that I had cors: true in my serverless.yml. I checked the CORS Headers in the AWS API Gateway for GET method for the notes resource. They are the following:
Access-Control-Allow-Headers 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
Access-Control-Allow-Methods 'OPTIONS,GET,POST'
Access-Control-Allow-Origin '*'

Still I cannot get this to work. Usually I develop REST API's with Node.js and Express. I use the CORS node.js package to enable CORS. With this I have never had the issue described above.

I am sure that there is something I am just missing. I really appreciate your help and want to do a lot more with serverless. Thank you!

@pmuens

This comment has been minimized.

Member

pmuens commented Dec 10, 2016

@lakinducker thanks for the question.
Could you paste your serverless.yml here real quick?

In the meantime you might also want to take a look at the docs about CORS setup: https://serverless.com/framework/docs/providers/aws/events/apigateway#enabling-cors

@lakinducker

This comment has been minimized.

lakinducker commented Dec 10, 2016

service: note-rest-api

frameworkVersion: ">=1.1.0 <2.0.0"

provider:
  name: aws
  runtime: nodejs4.3
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-1:*:*"

functions:
  create:
    handler: notes/create.create
    events:
      - http:
          path: notes
          method: post
          cors: true

  list:
    handler: notes/list.list
    events:
      - http:
          path: notes
          method: get
          cors: true

  get:
    handler: notes/get.get
    events:
      - http:
          path: notes/{id}
          method: get
          cors: true

  update:
    handler: notes/update.update
    events:
      - http:
          path: notes/{id}
          method: put
          cors: true

  delete:
    handler: notes/delete.delete
    events:
      - http:
          path: notes/{id}
          method: delete
          cors: true

resources:
  Resources:
    NotesDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        AttributeDefinitions:
          -
            AttributeName: id
            AttributeType: S
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: 'notes'
@lakinducker

This comment has been minimized.

lakinducker commented Dec 10, 2016

Is it a problem that the indents where lost in pasting it?

@pmuens

This comment has been minimized.

Member

pmuens commented Dec 10, 2016

@lakinducker Thanks
No problem! I updated your comment with the corresponding markdown and now the indentation is back.

You're using the LAMBDA-PROXY integration which means that your response needs the Access-Control-Allow-Origin header.

Here's an example how this looks like (taken from the docs):

'use strict';

exports.handler = function(event, context, callback) {

    const response = {
      statusCode: 200,
      // HERE'S THE CRITICAL PART
      headers: {
        "Access-Control-Allow-Origin" : "*" // Required for CORS support to work
      },
      body: JSON.stringify({ "message": "Hello World!" })
    };

    callback(null, response);
};
@lakinducker

This comment has been minimized.

lakinducker commented Dec 10, 2016

That worked! It is really great seeing this working with Angular 2. I made the mistake of not including the

headers: {
  "Access-Control-Allow-Origin" : "*" // Required for CORS support to work
}

in my Lambda functions. I won't make that mistake again. Learn something every day. I really appreciate your help!

@pmuens

This comment has been minimized.

Member

pmuens commented Dec 11, 2016

@lakinducker great to hear that this fixed your problem! 🎉

We're happy to help! Just let us know if you have any problems / need help! 👍

@TimothyDalbey

This comment has been minimized.

TimothyDalbey commented Dec 20, 2016

I tried to delete a stack and redeploy it (for a variety of reasons, none of which fit within the context of this discussion) and was getting the same error message. With a little investigation I determined that the reason for the error was that the original Cloudformation delete was not successful (I had done some manual bootstrapping after an initial deployment which is why the delete was not working...)

Once I manually deleted the Stack to success, the deploy method worked fine.

@reddhouse

This comment has been minimized.

reddhouse commented Feb 22, 2017

Hi Team Serverless. Thanks for your great framework! I followed your YouTube tutorials "Building a REST API with Lambda & DynamoDB", and my requests/responses are working fine from the terminal (with curl). However, when I try the same 'get' from inside my locally hosted Vue/Webpack app (using the axios library), I'm getting the same error that @lakinducker mentioned above:

XMLHttpRequest cannot load https://thgc79u8ol.execute-api.us-east-1.amazonaws.com/dev/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

I tried all of the suggestions above, including setting the Access-Control-Allow-Origin to '*' inside of both the list.js and get.js handlers, and also giving axios the following configuration in my app's get request:

headers: { 'Content-Type': 'application/json' }

Still, no luck. Any ideas?

@pmuens

This comment has been minimized.

Member

pmuens commented Feb 23, 2017

Hey @reddhouse thanks for the kind words!

We've open sourced have a fully fledged Serverless application called "Scope" recently. You can see the source code here: https://github.com/serverless/scope

It integrates the backend and frontend.

The serverless.yml with CORS setup can be found here: https://github.com/serverless/scope/blob/master/backend/serverless.yml

@bfred-it

This comment has been minimized.

bfred-it commented Mar 10, 2017

Dumb question: if I have to manually add this to the response:

      headers: {
        "Access-Control-Allow-Origin" : "*" // Required for CORS support to work
      },

What does cors: true do?

  get:
    handler: notes/get.get
    events:
      - http:
          path: notes/{id}
          method: get
          cors: true ///<---
@kiwifellows

This comment has been minimized.

kiwifellows commented Mar 12, 2017

@bfred-it the cors:true adds support on the API Gateway side, not in the Lambda function itself. Also the documentation for serverless states that cors: true does the following:

cors:
            origins:
              - '*'
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
            allowCredentials: false

See https://serverless.com/framework/docs/providers/aws/events/apigateway/

@ithinco

This comment has been minimized.

ithinco commented Mar 30, 2017

@kiwifellows I encountered the same issue as @reddhouse ,also tried all of the suggestions above, and looked at the source code of Scope.

Just don't know where I got wrong.:(

@pmuens

This comment has been minimized.

Member

pmuens commented Mar 30, 2017

@ithinco could you please share your serverless.yml and handler file so that we can take a look at it? Thanks!

@ithinco

This comment has been minimized.

ithinco commented Mar 31, 2017

There is no need to.:P

  1. add headers to all of the responses of aws-node-rest-api-with-dynamodb in the examples repo,
// create a response
    const response = {
      headers: {
        "Access-Control-Allow-Origin" : "*",
      },
      statusCode: 200,
      body: JSON.stringify(result.Item),
    };

2.deployed aws-node-rest-api-with-dynamodb in the examples repo to aws
3. enable cors
qq20170331-091954
4. curl https://ahhwlczx6f.execute-api.us-east-1.amazonaws.com/dev/todos
got []
5.

$.ajax({
	  url: 'https://ahhwlczx6f.execute-api.us-east-1.amazonaws.com/dev/todos',
	  method: 'get',
	  crossDomain: true,
	  data: '',
	  contentType: 'application/json',
	  headers: {
      "Access-Control-Allow-Origin" : "*",
    },
	}).done(function(response) {
	    console.dir(response);
	});

got error in the browser console

XMLHttpRequest cannot load https://ahhwlczx6f.execute-api.us-east-1.amazonaws.com/dev/todos. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.

the network log

General
Request URL:https://ahhwlczx6f.execute-api.us-east-1.amazonaws.com/dev/todos
Request Method:OPTIONS
Status Code:200 
Remote Address:54.230.213.96:443

Response Headers
access-control-allow-credentials:false
access-control-allow-headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
access-control-allow-methods:OPTIONS,GET,POST
access-control-allow-origin:*
content-length:0
content-type:application/json
date:Fri, 31 Mar 2017 01:18:05 GMT
status:200
via:1.1 7a87f44170a64ca50a528a4a5e5a1b16.cloudfront.net (CloudFront)
x-amz-cf-id:3STMXMdg3WUb3EatZQghvxeD45hLpnm2U2P-V9DcPVQHRqN3hnHpnQ==
x-amzn-requestid:e43aacb6-15af-11e7-9e7e-af7a8ba2ce01
x-cache:Miss from cloudfront

Request Headers
:authority:ahhwlczx6f.execute-api.us-east-1.amazonaws.com
:method:OPTIONS
:path:/dev/todos
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch, br
accept-language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
access-control-request-headers:access-control-allow-origin, content-type
access-control-request-method:GET
origin:http://localhost:3001
referer:http://localhost:3001/
user-agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36

@pmuens @kiwifellows

Update:

I see where I got wrong.

In the request headers.
access-control-request-headers:access-control-allow-origin, content-type

In the response headers.
access-control-allow-headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token

no access-control-allow-origin.

I deleted it from jquery options, it works in the browser!

@pmuens

This comment has been minimized.

Member

pmuens commented Mar 31, 2017

@ithinco thanks for sharing! Nice to hear that the problem was resolved.

@algera

This comment has been minimized.

algera commented Apr 6, 2017

Hmm, I appear to be stuck on getting an API to respond using CORS. Following the documentation as well as this thread, I am unable to receive a valid response from API Gateway. The error seems to be coming from the OPTIONS endpoint which gets automatically created when deploying.

Here is some relevant information, any help would be much appreciated. cc: @pmuens @ithinco

Serverless Version

sls --version
1.10.2

Received Error:

OPTIONS https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/v1/artists 403 ()
dispatchXhrRequest @ xhr.js:175
xhrAdapter @ xhr.js:12
dispatchRequest @ dispatchRequest.js:52
localhost/:1 XMLHttpRequest cannot load https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/v1/artists. 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:3000' is therefore not allowed access. The response had HTTP status code 403.

Network Monitor

Request URL:https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/v1/artists
Request Method:OPTIONS
Status Code:403 
Remote Address:52.84.239.157:443

Response Headers
content-length:23
content-type:application/json
date:Wed, 05 Apr 2017 23:56:54 GMT
status:403
via:1.1 a699d70234678d4cbb0dd9xxxxxxxxxx.cloudfront.net (CloudFront)
x-amz-cf-id:I25_rqa-sTOST8LHZED2NkKrz7_lWDm8w8c1yhNNbBxxxxxxxxxxxx==
x-amzn-errortype:ForbiddenException
x-amzn-requestid:8b7b50a7-1a5b-11e7-ac26-7f123301b7e8
x-cache:Error from cloudfront

Request Headers
:authority:XXXXXXXXXX.execute-api.us-east-1.amazonaws.com
:method:OPTIONS
:path:/v1/artists
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
access-control-request-headers:access-control-allow-origin, authorization, content-type, x-amz-date, x-amz-security-token
access-control-request-method:GET
cache-control:no-cache
dnt:1
origin:http://localhost:3000
pragma:no-cache
referer:http://localhost:3000/
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

Serverless Configuration (relevant pieces)

custom:
  versionPath: v1
  cors: true

functions:
  artists-read:
    handler: artist/readArtists.handler
    events:
      - http:
          path: ${self:custom.versionPath}/artists
          method: get
          cors: ${self:custom.cors}

resources:
  Resources:
    ApiGatewayMethodV1ArtistsGet:
      Type: "AWS::ApiGateway::Method"
      Properties:
        AuthorizationType: AWS_IAM

Lambda response code

(although I do not think it gets this far)

const response = {
  "statusCode": statusCode,
  "headers": {
        "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
        "Access-Control-Allow-Credentials" : true, // Required for cookies, authorization headers with HTTPS 
        "Content-Type": "application/json"
  },
  "body": JSON.stringify(data)
};
this.context.succeed(response);

Front-end request

    var headers = {
      headers: {
        "Access-Control-Allow-Origin" : "*"
      }
    };  
    var apigClient = apigClientFactory.newClient(config);
    const request = apigClient.invokeApi(params, pathTemplate, method, headers, body);
@Andriy-Kulak

This comment has been minimized.

Andriy-Kulak commented Apr 10, 2017

I followed all the instructions above and I still get the CORS error when I try to do a Post request. The request works well when I tested it locally but CORS shows up when I deploy to AWS. Any suggestions??

I tried the following multiple times after ensuring lambda function works locally (via serverless-offline)

  • added cors for my function in serverless.yml.
  • added the header to response in my handler
  • deploy to AWS
module.exports.upload = (event, context, callback) => {
...
      const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin" : "*" // Required for CORS support to work
          },
        body: {
          "data" : "test123"
        }
      };
      callback(null, response);

my serverless.yml

functions:
  hello:
    handler: functions/upload/handler.upload
    events:
      - http:
          path: upload
          method: post
          cors: true

My front-end code is a simple axios POST request which has been working well in regular node/express environment

  axios.post(UPLOAD_URL, imageData)
    .then((response) => {
      // If request is good...
      console.log('PASS', response);
    }, (err) => {
      console.log('error', err);
    })
    .catch((err) => {
      console.log('error Catch', err);
    });
@pmuens

This comment has been minimized.

Member

pmuens commented Apr 24, 2017

@Andriy-Kulak the CORS settings look good. Nothing wrong there as far as I can tell. Have you tried to do a request with a different tool / e.g. looked into it with the developer tools of your browser?

Otherwise you could try to use the LAMBDA integration type:

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          integration: LAMBDA
          path: hello
          method: get
          cors: true
'use strict';

module.exports.hello = (event, context, callback) => {
  callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
};
@dashmug

This comment has been minimized.

dashmug commented May 29, 2017

I'm having this problem with one project that uses lambda-proxy. I have another project that uses integration: lambda and CORS is working fine. But for these two, I can't get it to work.

The request works properly in Postman and the response headers already include Access-Control-Allow-Origin as you can see below.

screen shot 2017-05-29 at 5 39 31 pm

However, it still fails on the browser.

serverless.yml

events:
      - http:
          path: "/graphql"
          method: get
          authorizer: ${self:custom.authorizer}
          cors: true
@pmuens

This comment has been minimized.

Member

pmuens commented May 29, 2017

@dashmug thanks for commenting. What error message does your browser return?

We're currently fixing a CORS W3C incompatibility in #3692

@dashmug

This comment has been minimized.

dashmug commented May 29, 2017

It's just the usual CORS error.

XMLHttpRequest cannot load ...
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:3000' is therefore not allowed access. The response had HTTP status code 400.
@wesbasinger

This comment has been minimized.

wesbasinger commented May 29, 2017

I've been working through some of the same issues. Adding the right header in my lambda response helped my GET requests to go through, but my POST request is a no-go currently.

@pmuens

This comment has been minimized.

Member

pmuens commented May 30, 2017

@wesbasinger thanks for the feedback 👍

Could you please share your header config?

@gerrypower

This comment has been minimized.

gerrypower commented Jun 9, 2017

I also see issues with the POST cors request. Using curl, I see the preflight OPTIONS header includes 'Access-Control-Allow-Origin: *', whereas the curl POST to the endpoint does not. My workaround is to go to the console and select 'Enable Cors' for that endpoint and redeploy. Then the 'Access-Control-Allow-Origin: *' header shows up both in the preflight and the actual POST.

Here is my serverless.yml section:

functions:
  textToSpeech:
    handler: handler.textToSpeech
    events:
      - http:
          path: textToSpeech
          method: post
          cors:
            origins:
              - '*'
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: false
          integration: LAMBDA
          contentHandling: CONVERT_TO_BINARY
          request:
            passThrough: WHEN_NO_MATCH
            template:
              application/json: '{ "body-json": $input.json(''$'') }'
@ghost

This comment has been minimized.

ghost commented Jun 19, 2017

Dear Serverless,
I follow the guide from your links https://serverless.com/framework/docs/providers/aws/events/apigateway/ to enable CORS but it did not work. After spending many hours google around the internet, I found that your documents has a typos in the keyword "origin". It should be "origins" instead of "origin". Please restructure your docs to make your example it work correctly, thanks.

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          cors:
            origin: '*'
            headers:
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: false
@dashmug

This comment has been minimized.

dashmug commented Jun 19, 2017

@DE-Vanvo Good job discovering that.

You can edit the docs yourself. There's an "Edit on GitHub" link at the side of the document you linked.

@pmuens

This comment has been minimized.

Member

pmuens commented Jun 19, 2017

@DE-VanVo thank you for your feedback. origin should work with one of the recent Serverless versions.

We've added this property a few versions back so you should be able to use this is you're running an up to date Serverless version (docs always reflect the most recent Serverless version).

Edit: Here's the corresponding PR which introduces the changes: #3692.

@QuantumInformation

This comment has been minimized.

Contributor

QuantumInformation commented Sep 9, 2017

So I've added this to my lambda:

"Access-Control-Allow-Origin" : "*"

with

functions:
  sendMail:
    handler: lambda/mailServices.sendMail
    events:
        - http:
            path: sendMail
            method: post
            cors: true

and in the front end I do:

    fetch('https://216z7mamc7.execute-api.eu-west-2.amazonaws.com/dev/sendMail', {

      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },

      body: JSON.stringify(body)
    })

Is it correct, I'm getting No 'Access-Control-Allow-Origin' header is present on the requested resource. from the backend

I tried mode: 'cors',
and
type: 'cors',
with fetch but still no luck

@pmuens

This comment has been minimized.

Member

pmuens commented Sep 10, 2017

Thanks for commenting @QuantumInformation 👍

Could you post the code of your Lambda function? Does your code look smth. like this?

@joshisimt

This comment has been minimized.

joshisimt commented Sep 11, 2017

Hi @pmuens ,

I am using Angular 2 , keycloak and spring boot.

In case of redirecting from angular2 to keycloak page and getting same error-
XMLHttpRequest cannot load http://localhost:9090/auth/realms/paydbackend/protocol/openid-connect/auth?…roducts&state=3543d363-9c94-462c-afaf-052277353f9f&login=true&scope=openid. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

From the angular code I am doing following call-
getProducts() { return this.http.get('/api/products') .map((res:Response) => res.json()).subscribe(profile => this.profile = profile); }

Also tried this one
` getProducts() {
let headers = new Headers({ 'Access-Control-Allow-Origin': '*','Access-Control-Allow-Credentials':'true' });

return this.http.get('/api/products',headers)
            .map((res:Response) => res.json()).subscribe(profile => this.profile = profile);

}
`

Backend /api/prodcts is secured by keycloak.

I have also added web origins property to * in keycloak configuration but still no luck.

Can you please help?

Thanks

@QuantumInformation

This comment has been minimized.

Contributor

QuantumInformation commented Sep 11, 2017

I resolved it, I added

headers: {
'Access-Control-Allow-Origin': '*', // Required for CORS support to work
'Access-Control-Allow-Credentials': true, // Required for cookies, authorization headers with HTTPS
},
but was still getting a similar error, but the lambda was being called, it was an issue with my node code.

thanks

@pmuens

This comment has been minimized.

Member

pmuens commented Sep 11, 2017

@QuantumInformation thanks for sharing. Glad to hear that you were able to resolve the problem 👍

@joshisimt

This comment has been minimized.

joshisimt commented Sep 11, 2017

Can you please help on above ?

@dashmug

This comment has been minimized.

dashmug commented Sep 11, 2017

@joshisimt
What does your lambda function return?
Have you read this page?
Are you using Lambda Proxy Integration or Lambda Integration?
Have you added headers as well?

e.g.

{
    'Access-Control-Allow-Origin': '*', // Required for CORS support to work
}
@joshisimt

This comment has been minimized.

joshisimt commented Sep 11, 2017

@dashmug I am not using either Lambda integration or Lambda Proxy Integration.

@dashmug

This comment has been minimized.

dashmug commented Sep 11, 2017

@joshisimt What are you using then? Please provide more information.

Even better, try using https://gitter.im/serverless/serverless to ask for help.

@Toosick

This comment has been minimized.

Contributor

Toosick commented Oct 4, 2017

Idea: Here is another reason I ran into not receiving the CORs headers. I found that you won't receive headers on your requests that get returned by the default AWS API Gateway responses. You can manually set the headers on the default responses for your gateway in the AWS console. I don't know if you can set these in the Serverless config or not.

Example: I was running a 30+ second Lambda function that was returning a 504 Integration timeout. The response was coming back from API gateway without the cors headers. I had all the cors header correct in code like most people have said in this thread.

Solution: get the response down below 10 seconds because 30 seconds is a hard cap for API gateway and can't be increased.

@thesolotraveller

This comment has been minimized.

thesolotraveller commented Oct 5, 2017

@pmuens Thanks a lot. Got the CORS issue with serverless resolved.
Awesome.

@gabrielkaputa

This comment has been minimized.

gabrielkaputa commented Oct 10, 2017

Hi,

I had the same issue with cors. I'm using lambda-proxy, the headers in the response are set, cors: true was also set but i still had the issue with missing Access-Control-Allow-Origin header. I solved it by removing authorizer: aws_iam from serverless.yml from the function. Is it a good way to solve it? The API worked just fine from everywhere else, except the browser.

@flameoftheforest

This comment has been minimized.

flameoftheforest commented Nov 15, 2017

Hi,

Here's my serverless.yml

custom:
  allowed-headers:
    - Content-Type
    - X-Amz-Date
    - Authorization
    - X-Api-Key
    - X-Amz-Security-Token
    - X-Amz-User-Agent
    - X-Cowabunga
functions:
  Registration:
    handler: ArmaBackending::Backckending.MahAPI::Register
    role: superSpecialRole
    events:
      - http:
          path: sillyputty
          method: post
          cors:
            origin: "*"
            headers: ${self:custom.allowed-headers}
            allowCredentials: true
  RetrieveDetails:
    handler: ArmaBackending::Backckending.MahAPI::Details
    role: superSpecialRole
    events:
      - http:
          path: sillyputty/puttysilly
          method: get
          request:
            parameters:
              paths:
                type: true
          cors:
            origin: "*"
            heanders: ${self:custom.allowed-headers}
            allowCredentials: true
  • For POST [URL]/sillyputty, the CORS OPTIONS preflight returns the correct access-control-request-headers specified in the self:custom.allowed-headers. i. e.: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent,X-Cowabunga
  • However, GET [URL]/sillyputty/puttysilly, the CORS OPTIONS preflight returns the default Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
  • I can observe the Header Mappings exhibiting the above in Access-Control-Allow-Headers in API-Gateway Dashboard.

Can someone help me to understand what I did wrong?

Thank you very much!

@saurshaz

This comment has been minimized.

saurshaz commented Nov 18, 2017

@flameoftheforest & others Lambda shall contain the cors allowance headers as listed in https://github.com/serverless/serverless/issues/4037 . Nothing on client side shall matter much

@kiwifellows

This comment has been minimized.

kiwifellows commented Nov 20, 2017

Hi guys,
Just a note related to this error.

I noticed the browser will sometimes get a CORS error when I had my UI talking to the back end serverless API. I realsied the issue wasn't actually the configuration in Serverless itself but was an issue when a particular Lambda function crashed / 500/403 error. When this happens behind API Gateway, if you don't have a handler in Lambda to handle an error and put out a response then a 500 error or 403 access denied error will occur causing the browser to think that CORS is not enabled...

Hope that helps.

cheers,

Ben

@mocon

This comment has been minimized.

mocon commented Jan 29, 2018

Thank you @pmuens!

@ozbillwang

This comment has been minimized.

ozbillwang commented Apr 18, 2018

I have same issue as #1955 (comment)

@pmuens 's solution is helpful for any http calls with lambda function, but in my case, I use http-proxy integration, which doesn't need lambda function.

I try to add headers in serverelss.yml, but don't fix this issue.

      cors:
        origins:
          - "*"
        headers:
          - Content-Type
          - X-Amz-Date
          - Authorization
          - X-Api-Key
          - X-Amz-Security-Token
          - X-Amz-User-Agent
          - Access-Control-Allow-Headers
          - Access-Control-Allow-Origin
          - Access-Control-Allow-Methods

anything else I can do?

updates

Above setting works in fact.

@leantide

This comment has been minimized.

leantide commented May 6, 2018

Having cors:true and the Access-Control-Allow- headers described in the thread, it turns out that I was getting the cors issue because I was running on nodejs 8.10 (now supported by AWS) and not on nodejs 6.10 (older version still supported by AWS).

@ozbillwang

This comment has been minimized.

ozbillwang commented May 7, 2018

@leantide

Does serverless framework formally support nodejs 8.10 already? Any official document about it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment