SAM声明中如何阻止APIGateway覆盖Lambda返回的CORS响应头
解决API Gateway覆盖Lambda自定义OPTIONS响应CORS头的方案
- 第一步:删除
AWS::Serverless::Api资源下的全局Cors配置块
你在TESTAPI的Properties中配置的Cors字段是API Gateway托管OPTIONS响应的开关,只要保留该配置,APIGW就会自动拦截所有OPTIONS请求的响应,用你配置的固定CORS头覆盖Lambda返回的内容,这就是响应头被覆盖的核心原因。 - 第二步:调整Lambda事件配置,单独放开OPTIONS方法的授权校验
你当前用ANY方法绑定了Cognito授权,而浏览器发起的OPTIONS预检请求默认不会携带身份凭证,会直接被授权器拦截返回401导致跨域失败。你需要将原有事件拆分为两个配置,排除OPTIONS的授权校验:
TESTEndpoint: Type: AWS::Serverless::Function Properties: FunctionName: TEST_endpoint Handler: package/module.handler_any Events: # 除OPTIONS外的其他请求走授权校验 HttpNonOptions: Type: Api Properties: Path: '/path/endpoint' Method: "ANY" RestApiId: !Ref TESTAPI Auth: Authorizer: MyAuthorizer ExcludeOperation: ["OPTIONS"] # OPTIONS请求跳过授权,直接进入Lambda处理 HttpOptions: Type: Api Properties: Path: '/path/endpoint' Method: OPTIONS RestApiId: !Ref TESTAPI Auth: Authorizer: NONE
- 第三步:在Lambda代码中动态生成CORS头
你可以直接在handler中判断请求源是否属于允许的源站列表,自定义返回OPTIONS响应的CORS头,示例逻辑(Python为例):
# 配置你允许的所有源站 ALLOWED_ORIGINS = {"https://example.com", "https://test.com", "https://app.domain.com"} def handler_any(event, context): origin = event["headers"].get("origin") # 处理OPTIONS预检请求 if event["httpMethod"] == "OPTIONS": headers = { "Access-Control-Allow-Origin": origin if origin in ALLOWED_ORIGINS else "", "Access-Control-Allow-Credentials": "true", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Headers": "*" } return { "statusCode": 200, "headers": headers, "body": "" } # 其他方法的原有业务逻辑,返回时也按需带上对应CORS头即可 # ...
调整完成后APIGW不会再干预OPTIONS请求的响应内容,完全以Lambda返回的头信息为准,即可实现多源站的动态CORS配置。
内容的提问来源于stack exchange,提问作者AngelGabriel
相关产品推荐
相关产品推荐

