我正在尝试使用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
)。我了解人们以前曾遇到过这个问题,但是我找不到任何能够解决我问题的答案。
这里是my template。
请注意,"method.response.header.Access-Control-Allow-Origin": false
实际上使用与工作API相同的设置来创建API。
我还使用了correct answer for this question中的代码。
以下是dannymac的回答。我得到这些:
console.log(event.requestContext);
。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/welcome
Time (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
中使用Swagger模板,但无法解决无效的授权者问题。答案 0 :(得分:1)
我的最佳猜测:您的POST
lambda函数的ANY
在执行期间失败,并且没有将Access-Control-Allow-Origin
标头设置为*
(或您的域)。每当我从一个非5XX
的请求中同时收到一个CORS
错误和一个OPTIONS
错误时,对我来说几乎总是这样。
推荐的下一步:在将调试日志记录添加到Lambda源代码并在API Gateway Rest API中打开CloudWatch Logs之后,重现错误情况。您可以通过以下方法来执行此操作:转到API网关控制台,单击Stages
> Prod
> Logs/Tracing
,然后检查以下两项:Enable CloudWatch Logs
(日志级别:{{1} })和INFO
。然后,您必须“部署”更改,以使更改生效。为此,请从Rest API的Enable Detailed CloudWatch Metrics
菜单中单击Actions
按钮,然后选择Resources
。我还建议您从Lambda函数记录Deploy API
(传递给您的处理程序的事件属性),以便将Lambda请求与API网关请求extendedRequestId
绑定。
API网关日志示例:
event.requestContext.extendedRequestId
相关的Lambda执行日志示例:
(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
其他想法:导出损坏的API和有效API的Swagger定义。比较,看看有什么不同。通过从控制台转到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
> Stages
> Prod
> Export
来执行此操作。它可能与CloudFormation模板不完全相同,但是非常接近。
答案 1 :(得分:1)
我已经解决了这个问题。主要有两件事:
IntegrationHttpMethod
必须为POST。我找到了答案here。AWS::Lambda::Permission
。
使用该模板,当您使用AWS::Lambda::Permission
时,它将显示API作为Lambda函数的触发器。
但是,如果您手动创建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"
},
"/*"
]
]
}
}
},
然后编辑ANY,使其看起来像这样
"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"
}]
}
},