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.
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
}
]
}