Я пытаюсь использовать CloudFormation для создания шлюза API, но у меня есть проблема с CORS.
Ошибка на фронтенде:
POST https://<>.execute-api.us-east-1.amazonaws.com/prod/<> 500
new:1 Access to XMLHttpRequest at '<>' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Method Request, Integration Request, Integration Response и Method Response для всех методов (включая OPTIONS).Я понимаю, что у людей была эта проблема раньше, но я не смог найти ответа, который решил бы мою проблему.
Вот мой шаблон.
Обратите внимание, что "method.response.header.Access-Control-Allow-Origin": false фактически создает API с теми же настройками, что и рабочий.
Я также использую код из файла правильный ответ на этот вопрос.
После ответа dannymac ниже. Я получил это:
console.info(event.requestContext); в свою лямбда-функцию (написанную на Node.js).2019-06-27T20:07:03.118Z 462b93b2-9d4b-4ed3-bc04-f966fcd034cf Debug CORS issue. Request ID:
2019-06-27T20:07:03.118Z 462b93b2-9d4b-4ed3-bc04-f966fcd034cf undefined
event.requestContext.Enable CloudWatch Logs-INFO и Enable Detailed CloudWatch Metrics с CloudWatch log role ARN*:arn:aws:iam::<ID>:role/ApiGatewayCloudWatchLogsRole (это роль, созданная AWS) в настройках API Gateway.CloudWatch журнала API Gateway нет. В журнале по умолчанию CloudWatch - Log Groups: /aws/apigateway/welcomeTime (UTC +00:00)
2019-06-27
19:50:55
Cloudwatch logs enabled for API Gateway
CloudWatch не получил тест от API Gateway.GET в моем API Gateway:Response Body
{
"message": "Internal server error"
}
Response Headers
{}
Logs
Execution log for request 10d90173-9919-11e9-82e1-dd33dda3b9df
Thu Jun 27 20:20:54 UTC 2019 : Starting execution for request: 10d90173-9919-11e9-82e1-dd33dda3b9df
Thu Jun 27 20:20:54 UTC 2019 : HTTP Method: GET, Resource Path: /notes
Thu Jun 27 20:20:54 UTC 2019 : Method request path: {}
Thu Jun 27 20:20:54 UTC 2019 : Method request query string: {userid=<ID>}
Thu Jun 27 20:20:54 UTC 2019 : Method request headers: {}
Thu Jun 27 20:20:54 UTC 2019 : Method request body before transformations:
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:770402430649:function:test-api-gateway-2-LambdaFunction-1XDONAN3QIY9I/invocations
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request headers: {x-amzn-lambda-integration-tag=... [TRUNCATED]
Thu Jun 27 20:20:54 UTC 2019 : Endpoint request body after transformations: {"resource":"/notes","path":"/notes","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":{"userid":"<USERID>"},"multiValueQueryStringParameters":{"userid":["<USERID>"]},"pathParameters":null,"stageVariables":null,"requestContext":{"path":"/notes","accountId":"<ID>"...,"identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"<ARN>","apiKeyId":"test-invoke-api-key-id","userAgent":..."test [TRUNCATED]
Thu Jun 27 20:20:54 UTC 2019 : Sending request to https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:<ID>:function:test-api-gateway-2-LambdaFunction-<STRING>/invocations
Thu Jun 27 20:20:54 UTC 2019 : Received response. Status: 403, Integration latency: 6 ms
Thu Jun 27 20:20:54 UTC 2019 : Endpoint response headers: {Date=Thu, 27 Jun 2019 20:20:54 GMT, Content-Length=130, Connection=keep-alive, x-amzn-RequestId=<ID>}
Thu Jun 27 20:20:54 UTC 2019 : Endpoint response body before transformations: <AccessDeniedException>
<Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>
Thu Jun 27 20:20:54 UTC 2019 : Lambda invocation failed with status: 403. Lambda request id: feb22917-0dea-4f91-a274-fb6b85a69121
Thu Jun 27 20:20:54 UTC 2019 : Execution failed due to configuration error:
Thu Jun 27 20:20:54 UTC 2019 : Method completed with status: 500
// working one:
"x-amazon-apigateway-any-method": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "noteid",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"security": [
{
"mobile-notes-api-authorizer": []
}
]
}
// not working one:
"x-amazon-apigateway-any-method": {
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
}
}
},
"security": [
{
"test-api-gateway-2-authorizer": []
}
]
}
"headers": {
"Access-Control-Allow-Origin": {
"type": "string"
},
"Access-Control-Allow-Methods": {
"type": "string"
},
"Access-Control-Allow-Headers": {
"type": "string"
}
}
Body моего шлюза API, но не смог решить проблему с недействительным авторизатором.Возможно, это будет полезно для вас: stackoverflow.com/questions/40292888/…
Спасибо @DeependraDangal, если вы посмотрите на мой шаблон, я использую код из этого исправленного ответа.
(Не беспокойтесь о нечетном отрицательном голосовании здесь. Комментировать это бесполезно, так как анонимный отрицательный голос уже давно ушел. Если необходимо, пишите свои ответы в комментариях, но, пожалуйста, не добавляйте комментарии для голосования к сообщениям - они не представляют интереса для большинства читателей).
Спасибо @halfer, я буду иметь это в виду.





Моя лучшая догадка: POST к вашей лямбда-функции ANY происходит сбой во время выполнения, а заголовок Access-Control-Allow-Origin не устанавливает значение * (или ваш домен). Каждый раз, когда я получаю ошибку 5XX и ошибку CORS одновременно из запроса, отличного от OPTIONS, это почти всегда так для меня.
Рекомендуемые следующие шаги: воспроизведите ситуацию с ошибкой после добавления ведения журнала отладки в исходный код Lambda и включения журналов CloudWatch в API-интерфейсе API Gateway Rest. Вы можете сделать это, перейдя в консоль API Gateway, щелкнув Stages > Prod > Logs/Tracing, а затем проверив эти два параметра: Enable CloudWatch Logs (уровень журнала: INFO) и Enable Detailed CloudWatch Metrics. Затем вы должны «развернуть» изменения, чтобы они вступили в силу. Сделайте это, нажав кнопку Actions в меню Resources вашего Rest API и выбрав Deploy API. Я также рекомендую регистрировать extendedRequestId (свойство события, переданное вашему обработчику) из вашей функции Lambda, чтобы связать запрос Lambda с запросом шлюза API: event.requestContext.extendedRequestId.
Примеры журналов шлюза API:
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Extended Request Id: b5zpBGS3IAMFvqw=
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Verifying Usage Plan for request: b66b3876-984b-11e9-95eb-dd93c7e40ca0. API Key: API Stage: 1234567890/Prod
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) API Key authorized because method 'ANY /forms' does not require API Key. Request will not contribute to throttle or quota limits
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Usage Plan check succeeded for API Key and API Stage 1234567890/Prod
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Starting execution for request: b66b3876-984b-11e9-95eb-dd93c7e40ca0
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) HTTP Method: GET, Resource Path: /forms
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Lambda execution failed with status 200 due to customer function error: select count(*) AS `count(*)` from (select `user`.* from `user` where (id IN ('some_id_123'))) as `temp` - Cannot enqueue Query after fatal error.. Lambda request id: 1ae2bb06-5347-4775-9277-caccc42f18f2
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) Method completed with status: 502
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) AWS Integration Endpoint RequestId : 1ae2bb06-5347-4775-9277-caccc42f18f2
(b66b3876-984b-11e9-95eb-dd93c7e40ca0) X-ray Tracing ID : 1-5d13cca0-3be96a1ab93a877edc70577c
Пример коррелированных журналов выполнения Lambda:
START RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2 Version: $LATEST
2019-06-26T19:50:56.391Z 1ae2bb06-5347-4775-9277-caccc42f18f2 { "extendedRequestId": "b5zpBGS3IAMFvqw = ", ... }
2019-06-26T19:50:57.853Z 1ae2bb06-5347-4775-9277-caccc42f18f2 { "errorMessage": "select count(*) AS `count(*)` from (select `user`.* from `user` where (id IN ('some_id_123'))) as `temp` - Cannot enqueue Query after fatal error.", ... }
END RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2
REPORT RequestId: 1ae2bb06-5347-4775-9277-caccc42f18f2 Duration: 1660.45 ms Billed Duration: 1700 ms Memory Size: 256 MB Max Memory Used: 57 MB
другие мысли: Экспорт определений Swagger как неработающего API, так и рабочего API. Сравните и посмотрите, что отличается. Сделайте это в консоли, выбрав Stages > Prod > Export > Export as Swagger + API Gateway Extensions. Возможно, это не совсем то же самое, что и шаблон CloudFormation, но очень близко.
Большое спасибо @dannymac! Позвольте мне попробовать то, что вы предложили, и вернуться к вам.
Об экспорте swagger. Я сделал это, а также openAPI, но мне не удалось заставить код swagger или openAPI работать внутри свойства Body объекта AWS::ApiGateway::RestApi из-за проблемы с авторизатором. Я обновлю свой вопрос.
Я сделал то, что вы предложили, но не смог найти проблему. Я обновил свой вопрос выше.
Я разобрался с проблемой. Есть 2 основные вещи:
IntegrationHttpMethod для Lambda должен быть POST. Я нашел ответ здесь.AWS::Lambda::Permission, позволяющего API Gateway вызывать функцию Lambda.
С шаблоном, когда вы используете AWS::Lambda::Permission, он будет отображать API как триггер вашей лямбда-функции.
Однако если вы вручную создадите шлюз API и свяжете его со своей функцией Lambda, он не будет отображать шлюз API в качестве триггера, но все равно будет работать.Итак, для шаблона, который я разместил выше, мне нужно было добавить это, чтобы он работал:
"LambdaPermission": {
"Type": "AWS::Lambda::Permission",
"Description": "Permission for API GateWay to invoke Lambda.",
"Properties": {
"Action": "lambda:invokeFunction",
"FunctionName": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:execute-api:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
{
"Ref": "ApiGateway"
},
"/*"
]
]
}
}
},
И отредактируйте метод ЛЮБОЙ, чтобы он выглядел так
"methodNotesANY": {
"Type": "AWS::ApiGateway::Method",
"DependsOn": "LambdaPermission",
"Properties": {
"AuthorizationType": "COGNITO_USER_POOLS",
"AuthorizerId": {
"Ref": "GatewayAuthorizer"
},
"RestApiId": {
"Ref": "ApiGateway"
},
"ResourceId": {
"Ref": "resourceNotes"
},
"HttpMethod": "ANY",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
},
"IntegrationResponses": [{
"StatusCode": "200"
}]
},
"MethodResponses": [{
"ResponseModels": {
"application/json": "Empty"
},
"StatusCode": "200"
}]
}
},
Хотел бы я увидеть ваш ответ раньше ... сэкономил бы мне часы копания ...
Иногда это происходит, когда предварительный запрос OPTIONS не имеет заголовка «Access-Control-Allow-Origin». Вы уже проверили это?