Reputation: 279
I'm creating a LambdaRestApi in CDK and I want to have both CORS enabled and add an ANY proxy using the addProxy
method.
I currently have the following CDK code:
const api = new LambdaRestApi(...); // This API has CORS enabled in defaultCorsPreflightOptions
const apiProxy = api.root.addProxy({
defaultMethodOptions: {
authorizationType: AuthorizationType.COGNITO,
authorizer: new CognitoUserPoolsAuthorizer(...),
}
});
The problem I'm running into is that while a proxy is created with the ANY
method, it also sets the OPTIONS
method to require authentication. I tried to add an OPTIONS
method to the proxy using addMethod
to override the authorizer but I get an error that there's already a construct with the same name. I'm also trying to avoid having to set the anyMethod
field in the proxy to be false and adding my own methods. Is there a way in the API Gateway CDK to set the default authorizer to only work for any method except the OPTIONS
method?
Upvotes: 3
Views: 4380
Reputation: 2017
There is also a possibility to remove the auth explicitly on the OPTIONS
method, here I also remove requirement for X-API-Key
in the requests
const lambdaApi = new apigateway.LambdaRestApi(...) // This API has CORS enabled in defaultCorsPreflightOptions
lambdaApi.methods
.filter((method) => method.httpMethod === "OPTIONS")
.forEach((method) => {
const methodCfn = method.node.defaultChild as apigateway.CfnMethod;
methodCfn.authorizationType = apigateway.AuthorizationType.NONE;
methodCfn.authorizerId = undefined;
methodCfn.authorizationScopes = undefined;
methodCfn.apiKeyRequired = false;
});
Upvotes: 3
Reputation: 21
I ran into the same issue when building a RestApi using the aws cdk. Here is a workaround where you can build the api piece by piece.
defaultCorsPreflightOptions
property, otherwise you will not be able to override Authorization on the OPTIONS method.import * as apigateway from '@aws-cdk/aws-apigateway';
import * as lambda from '@aws-cdk/aws-lambda';
const restAPI = new apigateway.RestApi(this, "sample-api");
const dataProxyLambdaFunction = new lambda.Function(this, "data-handler", {
code: lambda.Code.fromBucket(S3CODEBUCKET, "latest/js_data.zip"),
handler: "index.handler",
runtime: lambda.Runtime.NODEJS_14_X
});
const dataProxy = restAPI.root.addResource("data")
.addResource("{proxy+}");
dataProxy.addMethod("ANY", new apigateway.LambdaIntegration(dataProxyLambdaFunction , {
allowTestInvoke: true,
}), { authorizationType: apigateway.AuthorizationType.CUSTOM, authorizer: customLambdaRequestAuthorizer });
standardCorsMockIntegration
and optionsMethodResponse
object to reuse with other methods in my api.const ALLOWED_HEADERS = ['Content-Type', 'X-Amz-Date', 'X-Amz-Security-Token', 'Authorization', 'X-Api-Key', 'X-Requested-With', 'Accept', 'Access-Control-Allow-Methods', 'Access-Control-Allow-Origin', 'Access-Control-Allow-Headers'];
const standardCorsMockIntegration = new apigateway.MockIntegration({
integrationResponses: [{
statusCode: '200',
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': `'${ALLOWED_HEADERS.join(",")}'`,
'method.response.header.Access-Control-Allow-Origin': "'*'",
'method.response.header.Access-Control-Allow-Credentials': "'false'",
'method.response.header.Access-Control-Allow-Methods': "'OPTIONS,GET,PUT,POST,DELETE'",
},
}],
passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
requestTemplates: {
"application/json": "{\"statusCode\": 200}"
}
});
const optionsMethodResponse = {
statusCode: '200',
responseModels: {
'application/json': apigateway.Model.EMPTY_MODEL
},
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': true,
'method.response.header.Access-Control-Allow-Methods': true,
'method.response.header.Access-Control-Allow-Credentials': true,
'method.response.header.Access-Control-Allow-Origin': true,
}
};
dataProxy.addMethod("OPTIONS", standardCorsMockIntegration, {
authorizationType: apigateway.AuthorizationType.NONE,
methodResponses: [
optionsMethodResponse
]
});
When you deploy the API, you can verify using the API Gateway console that your methods have been setup correctly. The proxy's ANY method has authorization enabled while the OPTIONS method does not.
Reference to the GitHub issue that helped: GitHub Issue 'apigateway: add explicit support for CORS'
Upvotes: 2