Search code examples
amazon-web-servicesaws-cloudformationaws-api-gatewayamazon-cognitoaws-amplify

AWS Amplify API Gateway cors error after using authorizer: aws_iam


I have API Gateway endpoints which execute lambda functions. I want to protect my api endpoints with using aws_iam as authorizer. I have a user pool with federated identities set up for this. However after implementing it into the cloudformation template I get an cors error calling it from my angular app with an authenticated user:

Access to XMLHttpRequest at 'api endpoint url' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

here is the code of my cf template:

create:
handler: functions/api-create.create
events:
  - http:
      path: get/create
      method: get
      authorizer: aws_iam
      cors: true

my lambda function looks like this:

export const create = async (event, context) => {


console.log('Create: ', event)
  console.log('Context: ', context)
  const response = {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true,
    },
    body: JSON.stringify({
      product: "hallo"
    }),
  };

return response;
};

Without authorizer: aws_iam everything works fine and I get the expected response. Does anyone know what I could be missing here.


Solution

  • Found it out myself. Here is what I did.

    After creating resources for the GatewayResponsdefault errors that they also have the correct headers with this templates in my Serverless.yml file:

     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'
      GatewayResponseDefault5XX:
        Type: 'AWS::ApiGateway::GatewayResponse'
        Properties:
          ResponseParameters:
             gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
             gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
          ResponseType: DEFAULT_5XX
          RestApiId:
            Ref: 'ApiGatewayRestApi'
    

    The error I received changed to a 403 error. Now I enabled cloud watch logging for my api endpoint since I was calling the endpoint with an authorized user.

    There I saw now the error:

    "message": "Credential should be scoped to a valid region, not 'us-east-1'. "
    

    After a little trial and error I found our that since I am using amplify I had to pass in the region for the api on amplify configure like this:

    Amplify.configure({
    
    
    Auth: {
        mandatorySignIn: true,
        region: awsExports.cognito.REGION,
        userPoolId: awsExports.cognito.USER_POOL_ID,
        identityPoolId: awsExports.cognito.IDENTITY_POOL_ID,
        userPoolWebClientId: awsExports.cognito.APP_CLIENT_ID,
      },
      API: {
        endpoints: [
            {
                name: awsExports.api.name,
                endpoint: awsExports.api.endpoint,
                region: "eu-west-1" // <-- This was missing
            }
        ]
    }