为ECS后端VPC Proxy集成的AWS API Gateway未授权响应添加CORS头
解决API Gateway VPC Proxy+自定义授权Lambda的CORS 401响应问题
针对你遇到的场景,核心问题是授权阶段拦截的401响应无法动态匹配请求Origin并添加合规CORS头,以下是可行的解决思路和具体步骤:
核心方案:通过自定义授权Lambda传递Origin,配置动态网关响应
API Gateway的默认网关响应不支持动态Origin,但可以通过自定义授权Lambda将请求的Origin传递到上下文,再在自定义网关响应中引用这个动态值,同时解决泛域名匹配的问题。
1. 修改自定义授权Lambda,动态传递并验证Origin
在授权Lambda中提取请求的Origin头,验证其是否属于你的允许域名范围(比如匹配*.mydomain.com),然后将Origin放入响应的context字段中,无论授权通过或拒绝都传递这个值。
示例Python代码:
import json def lambda_handler(event, context): # 提取请求中的Origin头 request_origin = event.get('headers', {}).get('Origin', '') # 验证Origin是否属于允许的域名范围(支持所有mydomain.com子域名) is_allowed_origin = request_origin.endswith('.mydomain.com') # 生成授权策略 policy = { 'Version': '2012-10-17', 'Statement': [{ 'Action': 'execute-api:Invoke', 'Effect': 'Allow' if is_allowed_origin else 'Deny', 'Resource': event['methodArn'] }] } # 返回策略+携带Origin的上下文 return { 'principalId': 'auth-user' if is_allowed_origin else 'unauthorized', 'policyDocument': policy, 'context': { 'allowed_origin': request_origin if is_allowed_origin else '' } }
2. 配置API Gateway自定义网关响应
进入API Gateway控制台,针对UNAUTHORIZED(对应401状态码)配置自定义网关响应,添加动态CORS头:
- 找到API的网关响应(Gateway Responses)菜单
- 选择
UNAUTHORIZED类型,点击「编辑」 - 在响应头中添加:
Access-Control-Allow-Origin: $context.authorizer.allowed_originAccess-Control-Allow-Credentials: true
- (可选)添加其他需要的CORS头,比如
Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key
3. 处理OPTIONS预飞行请求
Axios会先发OPTIONS预飞行请求,需要确保该请求也能通过授权并返回正确CORS头:
- 为API的OPTIONS方法关联同一个自定义授权Lambda(或单独写一个允许所有合法Origin的OPTIONS授权逻辑)
- 同样在网关响应中为
OPTIONS对应的响应添加动态CORS头,确保预飞行请求不被拦截
为什么这个方案可行?
- 解决了
credentials: include模式下不能用*的问题:动态返回请求的真实Origin,符合浏览器的CORS规则 - 解决了API Gateway不支持泛域名的问题:在Lambda中通过字符串匹配验证Origin,支持所有
*.mydomain.com子域名 - 绕过了VPC Proxy集成无法配置集成响应的限制:通过网关响应直接处理授权阶段的错误返回
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

