CloudFormation API网关CORS发出对XMLHttpRequest的访问被阻止 [英] CloudFormation API Gateway CORS issue access to XMLHttpRequest blocked

查看:75
本文介绍了CloudFormation API网关CORS发出对XMLHttpRequest的访问被阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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的每个页面,并发现它们的方法请求集成请求集成响应方法响应的所有方法(包括 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 and Method Response for all the methods (including the OPTIONS).
    • 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 启用具有 CloudWatch日志角色ARN *的详细CloudWatch指标:在 API网关设置中,aws:iam ::< ID>:role / ApiGatewayCloudWatchLogsRole (由AWS创建的角色)。

      • 但是, API网关没有 CloudWatch 日志。 CloudWatch-日志组中有一个默认日志: / aws / apigateway / welcome

        • It looks like there is no event.requestContext.
        • I selected Enable CloudWatch Logs-INFO and Enable Detailed CloudWatch Metrics with CloudWatch log role ARN*:arn:aws:iam::<ID>:role/ApiGatewayCloudWatchLogsRole (it's a role created by AWS) in the API Gateway settings.
        • However, there is no CloudWatch log for the API Gateway. There's a default log in CloudWatch - 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 from API Gateway.
            • This is what I got from testing the GET method in my 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
              




              • 我还在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.
                    • 推荐答案

                      我已经解决了这个问题。主要有两件事:

                      I've figured out the issue. There are 2 main things:


                      1. Lambda的 IntegrationHttpMethod 必须为POST。我在此处找到了答案。

                      2. 模板没有 AWS :: Lambda :: Permission ,该API允许API网关调用Lambda函数。
                        使用该模板,当您使用 AWS :: Lambda :: Permission 时,它将显示API作为Lambda函数的触发器。
                        但是,如果您手动创建API网关并将其与Lambda函数链接,则它不会将API网关显示为触发器,但仍然可以使用。

                      1. The IntegrationHttpMethod for Lambda must be POST. I found the answer here.
                      2. The template didn't have AWS::Lambda::Permission that allows API Gateway to invoke Lambda function. With the template, when you use AWS::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.

                      因此,对于我上面发布的模板,我需要添加以下内容才能使其正常工作:

                      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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆