johnny_mac
johnny_mac

Reputation: 1951

Resource blocked by CORS policy in Serverless API Gateway Lambda even though its set up

I am using Serverless and I have a lambda that is available via API Gateway. Like many of the CORs questions that mention a similar stack, I am getting the following error when making a call from a browser (usual Postman/curl local testing works just fine):

Access to XMLHttpRequest at 'https://<gatewayUrl>/dev/login/?userType=userA' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field z-client-timezone is not allowed by Access-Control-Allow-Headers in preflight response

I'm extremely frustrated so any help would be awesome. One more thing, when I do curl -i -X OPTIONS https://<gatewayUrl>/dev/login I get this result, which seems to be missing Z-Client-Timezone:

HTTP/2 200
content-type: application/json
content-length: 0
date: Fri, 10 Jul 2020 04:00:10 GMT
x-amzn-requestid: <aws_requestId>
access-control-allow-origin: *
access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
x-amz-apigw-id: <apigw-id>
access-control-allow-methods: OPTIONS,POST
via: 1.1 <id>.cloudfront.net (CloudFront), 1.1 <id>.cloudfront.net (CloudFront)
x-amz-cf-pop: DFW50-C1
x-cache: Miss from cloudfront
x-amz-cf-pop: DFW55-C1
x-amz-cf-id: <cf-id>

My Lambda:

export async function login(event) {

    const headers = {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true
    }

    ....
    return {
      statusCode: 200,
      headers,
      body: JSON.stringify(session)
    };
}

My Serverless.yml:

login:
  handler: dist/src/handlers/auth.login
  events:
    - http:
        path: login
        method: post
        cors: 
          origin: '*'
          headers:
           - Access-Control-Allow-Credentials

resources:
  Resources:
    GatewayResponseDefault4XX:
        Type: 'AWS::ApiGateway::GatewayResponse'
        Properties:
            ResponseParameters:
              gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
              gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
            ResponseType: DEFAULT_4XX
            RestApiId:
              Ref: 'ApiGatewayRestApi'

I would love any help you can give. I've omitted some code as everything else works except for the cors stuff so I've just included that but if more clarification is needed, I'm happy to provide.

Upvotes: 1

Views: 1655

Answers (1)

Joseph Lane
Joseph Lane

Reputation: 221

While your lambda function is allowing the Z-Client-Timezone header, the built-in options method of AWS is not.

In order to allow this, you can do the following -

login:
  handler: dist/src/handlers/auth.login
  events:
    - http:
        path: login
        method: post
        cors: 
          origin: '*'
          headers:
           - Access-Control-Allow-Credentials
           - Z-Client-Timezone

Then add any other headers you are also sending.

Upvotes: 2

Related Questions