Включение CORS для шлюза API AWS с помощью AWS CDK
Я пытаюсь создать приложение с помощью AWS CDK, и если бы я собирал приложение вручную, используя консоль AWS, я обычно включал бы CORS в шлюзе API.
Несмотря на то, что я могу экспортировать сваггер из API-шлюза и найти множество вариантов генерации конечной точки Mock для метода OPTIONS, я не вижу, как это сделать с помощью CDK. В настоящее время я пытался:
const apigw = require('@aws-cdk/aws-apigateway');
где:
var api = new apigw.RestApi(this, 'testApi');
и определение метода OPTIONS, например:
const testResource = api.root.addResource('testresource');
var mock = new apigw.MockIntegration({
type: "Mock",
methodResponses: [
{
statusCode: "200",
responseParameters : {
"Access-Control-Allow-Headers" : "string",
"Access-Control-Allow-Methods" : "string",
"Access-Control-Allow-Origin" : "string"
}
}
],
integrationResponses: [
{
statusCode: "200",
responseParameters: {
"Access-Control-Allow-Headers" : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"Access-Control-Allow-Origin" : "'*'",
"Access-Control-Allow-Methods" : "'GET,POST,OPTIONS'"
}
}
],
requestTemplates: {
"application/json": "{\"statusCode\": 200}"
}
});
testResource.addMethod('OPTIONS', mock);
Но это не развертывание. Сообщение об ошибке, которое я получаю от развертывания стека облачной информации при запуске "cdk deploy":
Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression specified: Access-Control-Allow-Origin] (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException;
Идеи?
1 ответ
Я не проверял это сам, но на основе этого ответа кажется, что вам нужно будет использовать немного другой набор ключей при определении вашей интеграции MOCK:
const api = new apigw.RestApi(this, 'api');
const method = api.root.addMethod('OPTIONS', new apigw.MockIntegration({
integrationResponses: [
{
statusCode: "200",
responseParameters: {
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"method.response.header.Access-Control-Allow-Methods": "'GET,POST,OPTIONS'",
"method.response.header.Access-Control-Allow-Origin": "'*'"
},
responseTemplates: {
"application/json": ""
}
}
],
passthroughBehavior: apigw.PassthroughBehavior.Never,
requestTemplates: {
"application/json": "{\"statusCode\": 200}"
},
}));
// since "methodResponses" is not supported by apigw.Method (https://github.com/awslabs/aws-cdk/issues/905)
// we will need to use an escape hatch to override the property
const methodResource = method.findChild('Resource') as apigw.cloudformation.MethodResource;
methodResource.propertyOverrides.methodResponses = [
{
statusCode: '200',
responseModels: {
'application/json': 'Empty'
},
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': true,
'method.response.header.Access-Control-Allow-Methods': true,
'method.response.header.Access-Control-Allow-Origin': true
}
}
]
Было бы полезно иметь возможность включать CORS, используя более дружественный API.
Недавнее изменение сделало позволяет CORS проще:
const restApi = new apigw.RestApi(this, `api`, {
defaultCorsPreflightOptions: {
allowOrigins: apigw.Cors.ALL_ORIGINS
}
});
С недавними обновлениями CDK больше нет необходимости использовать аварийный люк.
Эта версия, изначально созданная Heitor Vital на github, использует только собственные конструкции.
export function addCorsOptions(apiResource: apigateway.IResource) {
apiResource.addMethod('OPTIONS', new apigateway.MockIntegration({
integrationResponses: [{
statusCode: '200',
responseParameters: {
'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'",
'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}"
},
}), {
methodResponses: [{
statusCode: '200',
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,
},
}]
})
}
Я также перенес тот же код на Python, используя его версию в качестве ориентира.
def add_cors_options(api_resource):
"""Add response to OPTIONS to enable CORS on an API resource."""
mock = apigateway.MockIntegration(
integration_responses=[{
'statusCode': '200',
'responseParameters': {
'method.response.header.Access-Control-Allow-Headers':
"'Content-Type,\
X-Amz-Date,\
Authorization,\
X-Api-Key,\
X-Amz-Security-Token,X-Amz-User-Agent'",
'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'",
}
}],
passthrough_behavior=apigateway.PassthroughBehavior.NEVER,
request_templates={
"application/json": "{\"statusCode\": 200}"
}
)
method_response = apigateway.MethodResponse(
status_code='200',
response_parameters={
'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
}
)
api_resource.add_method(
'OPTIONS',
integration=mock,
method_responses=[method_response]
)
ЗАДНИЙ ПЛАН
Я наткнулся на этот ответ, пытаясь реализовать aws_api_gateway_integration_response
в Terraform и случайно наткнулся на решение.
ПРОБЛЕМА
Я получал это сообщение об ошибке:
Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression specified: POST,GET,OPTIONS]
в aws_api_gateway_integration_response
ресурс у меня был response_parameter
ключ как:
response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
"method.response.header.Access-Control-Allow-Origin" = "*"
"method.response.header.Access-Control-Allow-Methods" = "POST,GET,OPTIONS"
# "method.response.header.Access-Control-Allow-Credentials" = "false"
}
Я думал, что все в порядке, так как предполагал, что Terraform нужны двойные кавычки. Однако это было не так.
РЕШЕНИЕ
Мне пришлось добавить одинарные кавычки вокруг значений внутри двойной кавычки. Как это:
response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
"method.response.header.Access-Control-Allow-Origin" = "'*'"
"method.response.header.Access-Control-Allow-Methods" = "'POST,GET,OPTIONS'"
# "method.response.header.Access-Control-Allow-Credentials" = "false"
}