繁体   English   中英

AWS Api 网关和 Cognito 导致 CORS 错误

[英]AWS Api Gateway and Cognito cause CORS errors

我不知道如何开始,在将 API 网关与 Cognito 作为授权方一起使用时,我遇到了 CORS 错误。 我在这上面花了很多时间,我相信我已经阅读了整个 inte.net 以弄清楚发生了什么和错了什么。 那么让我们从一个简单的例子开始。 我的 lambda:

import json
def handler(event, context):
    print('Lambda is here')
    return dict(
        statusCode=200,
        headers={
            'Access-Control-Allow-Headers': '*',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': '*',
            'Access-Control-Allow-Credentials': 'true',
        },
        body=json.dumps({'message': 'lambda works'})
    )

HTML测试CORS和授权的代码:

<head>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
        axios.get(
            "api_gateway_url",
        )
        .then(response =>alert(response.data.message))
        .catch(error => {
            console.log(error)
            alert("ERROR")
        })
</script>
</body>

对于API网关不认证,响应为:
在此处输入图像描述

对于API认证网关,响应为:
在此处输入图像描述 在此处输入图像描述

响应代码取决于 API 网关的配置。 我已经改变了很多次我能改变的一切,我正在通过设置测试它的设置,但没有任何帮助。 我在启用 CORS 配置下的方法响应、集成响应和网关响应等位置添加了 CORS 标头。 根据配置,我有一些状态代码 401、403 和 500,并且总是出现 CORS 错误。
虽然测试请求没有触及 lambda,因此上述错误不是 lambda 执行的结果。

我已经通过使用 CDK 部署它来测试它,我创建了一个示例代码,您也可以在本地环境中尝试。 代码链接https://gitlab.com/magnus250/cognito-api-gateway-cdk-problems/

好的,我终于解决了我的问题。 @sampath-dilhan @chris-smith 谢谢。 那么让我描述一下我是如何实现它的。

我认为整个 API 网关都被窃听了,你永远不知道你到底配置了什么。 API 网关的基础开发由 CDK 提供,然后我尝试不同的配置以从控制台启用 CORS。 我阅读了有关 CORS 配置的整个 inte.net,并尝试使用这些知识启用 CORS,总是重新部署 API 并等待一段时间直到测试。

下面我放了适合我的 CDK 配置。 对于遇到问题的人,我建议始终销毁您的堆栈并在干净的环境中重新部署它,因为正如我已经提到的,我相信 API 网关存在漏洞。 该代码还具有域和证书定义。

    def create_api_gateway(
        self,
        prefix: str,
        domain: str,
        certificate_arn: str,
        cognito_user_pool_arn: str,
        handler: _lambda.Function,
    ) -> None:
        base_api = apigateway.RestApi(
            self,
            f"{prefix}-authorized-rest-api",
            deploy_options=apigateway.StageOptions(
                throttling_burst_limit=100,
                throttling_rate_limit=100,
                caching_enabled=False,
                cache_cluster_enabled=False,
            ),
            default_cors_preflight_options=apigateway.CorsOptions(
                allow_headers=[
                    "Content-Type",
                    "X-Amz-Date",
                    "Authorization",
                    "X-Api-Key",
                ],
                allow_methods=["*"],
                allow_credentials=True,
                allow_origins=["*"],
            ),
            domain_name=apigateway.DomainNameOptions(
                certificate=certificatemanager.Certificate.from_certificate_arn(
                    self,
                    f"{prefix}-certificate",
                    certificate_arn=certificate_arn,
                ),
                domain_name=f"api.{domain}",
                endpoint_type=apigateway.EndpointType.EDGE,
            ),
        )
        response_types = [
            apigateway.ResponseType.DEFAULT_4_XX,
            apigateway.ResponseType.DEFAULT_5_XX,
        ]
        for response_type in response_types:
            base_api.add_gateway_response(
                f"{prefix}-api-gateway-{response_type.response_type}",
                type=response_type,
                response_headers={
                    "Access-Control-Allow-Origin": "'*'",
                    "Access-Control-Allow-Headers": "'*'",
                    "Access-Control-Allow-Methods": "'*'",
                    "Access-Control-Allow-Credentials": "'true'",
                },
            )

        user_pool = cognito.UserPool.from_user_pool_arn(
            self, f"{prefix}-user-pool", user_pool_arn=cognito_user_pool_arn
        )
        authorizer = apigateway.CognitoUserPoolsAuthorizer(
            self,
            f"{prefix}-authorizer",
            authorizer_name=f"{prefix}-authorizer",
            cognito_user_pools=[user_pool],
        )

        get_widgets_integration = apigateway.LambdaIntegration(handler)
        resource = base_api.root.add_resource("{proxy+}")
        resource.add_method(
            "ANY",
            get_widgets_integration,
            authorizer=authorizer,
        )

        cdk.CfnOutput(self, f"{prefix}-api-url", value=base_api.url)

        zone = route53.HostedZone.from_lookup(self, f"{prefix}-hosted-zone", domain_name=domain)
        route53.ARecord(
            self,
            f"{prefix}-dns-record",
            record_name="api",
            zone=zone,
            target=route53.RecordTarget.from_alias(route53_targets.ApiGateway(base_api)),
        )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM