CloudFormation API网关CORS发出对XMLHttpRequest的访问被阻止 [英] CloudFormation API Gateway CORS issue access to XMLHttpRequest blocked
问题描述
我正在尝试使用CloudFormation创建API网关,但是它存在CORS问题。
I'm trying to use CloudFormation to create an API Gateway but I have CORS issue with it.
前端错误:
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.
- 创建的API没有任何问题,我甚至仔细检查了在控制台上使用有效API的每个页面,并发现它们的
方法请求
,集成请求$ c $没有区别c>,
集成响应
和方法响应
的所有方法(包括OPTIONS
)。 - 如果我删除模板创建的资源,并在同一API网关中手动创建它们,则我的代码将按预期工作。我已经在S3存储桶和PostMan中使用了本地主机,前端代码进行了测试,因此可以验证前端代码,lambda函数和数据库是否正常工作。
-
我知道人们以前曾遇到过这个问题,但是我找不到解决我问题的答案。
- The API is created without any issue and I even double check every single page on the console against the working API and find no differences in their
Method Request
,Integration Request
,Integration Response
andMethod Response
for all the methods (including theOPTIONS
). - If I remove the resources created by the template and create them manually in the same API gateway then my code works as expected. I've tested with the localhost, front-end code in S3 bucket and PostMan, so I can verify that my front-end code, lambda functions and database are working correctly.
I understand that people have had this issue before but I haven't been able to find any answer that solves my issue.
这里是我的模板。
请注意
method.response.header.Access-Control-Allow-Origin:false
实际上创建的API与工作中的API相同。Please note that the
"method.response.header.Access-Control-Allow-Origin": false
actually creates the API with the same settings as the working one.我还使用了此问题的正确答案。
跟随dannymac的回答在下面。我得到了这些
Following dannymac's answer below. I got these:
- 我添加了
console.log(event.requestContext);
到我的Lambda函数(用Node.js编写)中。 - 测试该函数时,Lambda会有日志。
- I added
console.log(event.requestContext);
to my Lambda function (written in Node.js). - There are logs for Lambda when I test the function.
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
。 - 我选择了
启用CloudWatch Logs-INFO
和启用具有
(由AWS创建的角色)。CloudWatch日志角色ARN *的详细CloudWatch指标
:在API网关
设置中,aws:iam ::< ID>:role / ApiGatewayCloudWatchLogsRole - 但是,
API网关
没有CloudWatch
日志。CloudWatch-日志组
中有一个默认日志:/ aws / apigateway / welcome
- It looks like there is no
event.requestContext
. - I selected
Enable CloudWatch Logs-INFO
andEnable Detailed CloudWatch Metrics
withCloudWatch log role ARN*:arn:aws:iam::<ID>:role/ApiGatewayCloudWatchLogsRole
(it's a role created by AWS) in theAPI Gateway
settings. - However, there is no
CloudWatch
log for theAPI Gateway
. There's a default log inCloudWatch - Log Groups
:/aws/apigateway/welcome
Time (UTC +00:00) 2019-06-27 19:50:55 Cloudwatch logs enabled for API Gateway
-
CloudWatch
日志似乎没有从API网关
接受测试。 - 这是通过在我的
API网关
中测试GET
方法得到的: - It looks like the
CloudWatch
log didn't pick up the test fromAPI Gateway
. - This is what I got from testing the
GET
method in myAPI 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
- 我还在Swagger 2中导出了正常工作和不正常工作的API网关。唯一的区别是:
// 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" } }
- I曾尝试在我的API网关的
Body
中使用Swagger模板,但无法解决无效的授权者问题。 - I've tried to use the Swagger template in the
Body
of my API Gateway before but unable to solve the invalid authorizer issue. - Lambda的
IntegrationHttpMethod
必须为POST。我在此处找到了答案。 - 模板没有
AWS :: Lambda :: Permission
,该API允许API网关调用Lambda函数。
使用该模板,当您使用AWS :: Lambda :: Permission
时,它将显示API作为Lambda函数的触发器。
但是,如果您手动创建API网关并将其与Lambda函数链接,则它不会将API网关显示为触发器,但仍然可以使用。 - The
IntegrationHttpMethod
for Lambda must be POST. I found the answer here. - The template didn't have
AWS::Lambda::Permission
that allows API Gateway to invoke Lambda function. With the template, when you useAWS::Lambda::Permission
, it will show the API as a trigger of your Lambda function. However, if you manually create the API Gateway and link it with your Lambda function, it won't show API Gateway as a trigger but it still works.
推荐答案
我已经解决了这个问题。主要有两件事:
I've figured out the issue. There are 2 main things:
因此,对于我上面发布的模板,我需要添加以下内容才能使其正常工作:
So for the template I posted above, I needed to add these for it to work:
"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" }, "/*" ] ] } } },
并编辑方法看起来像这样的任何
And edit method ANY to look like this
"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" }] } },
这篇关于CloudFormation API网关CORS发出对XMLHttpRequest的访问被阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 我添加了
- The API is created without any issue and I even double check every single page on the console against the working API and find no differences in their