未认证方法遇Missing Authentication Token:API Gateway Terraform配置CORS接口curl报403
我之前遇到过完全一样的问题,控制台测试正常但curl调用失败,折腾了好久才找到几个关键的排查点,你可以逐一试试:
1. 确认API已重新部署
Terraform配置变更后,API Gateway不会自动更新已有的部署版本。控制台测试用的是最新的配置,但curl调用的可能是旧的部署快照。
确保你的Terraform代码里包含aws_api_gateway_deployment资源,并且添加触发器保证配置变更后自动重新部署:
resource "aws_api_gateway_deployment" "api_deployment" { rest_api_id = aws_api_gateway_rest_api.my_api.id stage_name = "prod" # 当API配置变更时自动触发重新部署 triggers = { redeployment = sha1(jsonencode([ aws_api_gateway_method.cors_method, aws_api_gateway_integration.cors_integration ])) } lifecycle { create_before_destroy = true } }
部署完成后,再用curl调用最新的阶段URL。
2. 检查方法的HTTP动词和路径是否完全匹配
API Gateway的路径和HTTP动词匹配是严格的,哪怕细微的差异都会导致找不到正确的方法,进而返回403错误:
- 确认curl调用的HTTP动词和Terraform中
aws_api_gateway_method的http_method一致(比如OPTIONS/GET/POST) - 检查路径是否带多余的斜杠:比如控制台测试的是
/my-endpoint,但curl调用的是/my-endpoint/,这会被视为不同的路径 - 验证Terraform中
aws_api_gateway_resource的路径设置和调用URL完全一致
3. 排查API Gateway的资源策略
即使方法设置了authorization = "NONE",如果API Gateway本身配置了资源策略(aws_api_gateway_rest_api_policy),可能会限制匿名访问。比如策略只允许特定IP、IAM用户或来源访问,这时候curl调用会被拦截。
如果需要允许匿名访问,可以调整资源策略为:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:${var.aws_region}:${var.aws_account_id}:${aws_api_gateway_rest_api.my_api.id}/*/*/*" } ] }
注意:根据实际业务需求调整资源策略的范围,避免过度开放。
4. 确认未开启API密钥要求
检查Terraform中aws_api_gateway_method或aws_api_gateway_method_settings的api_key_required属性是否设为false。如果这个值是true,即使授权方式是NONE,调用时也需要携带API密钥,否则会返回403。
示例配置:
resource "aws_api_gateway_method" "cors_method" { rest_api_id = aws_api_gateway_rest_api.my_api.id resource_id = aws_api_gateway_resource.my_resource.id http_method = "OPTIONS" authorization = "NONE" api_key_required = false # 确保这个值是false }
5. 验证curl命令的正确性
CORS请求需要携带Origin头,浏览器会自动发送,但curl需要手动添加。另外要确认调用的URL包含正确的阶段名称:
# 正确的curl命令示例,替换为你的API信息 curl -X OPTIONS \ -H "Origin: https://your-frontend-domain.com" \ https://<api-id>.execute-api.<region>.amazonaws.com/<stage>/<path>
如果没有添加Origin头,API Gateway可能不会触发CORS配置的响应逻辑,导致返回错误。
内容的提问来源于stack exchange,提问作者Naftuli Kay

