浏览器请求SAM部署的带Cognito授权的API Gateway出现CORS错误
问题根因
你为API Gateway配置了全局默认Cognito授权器,默认规则下所有请求(包括OPTIONS预检请求)都会触发授权校验。而浏览器发起的OPTIONS预检请求不会携带Authorization头,会直接被授权器拦截返回4xx错误,响应里自然不会包含CORS相关头,就触发了你看到的跨域错误。
解决方案
按以下步骤修改配置即可解决:
- 修改SAM模板中
AWS::Serverless::Api的Auth配置,添加AddDefaultAuthorizerToCorsPreflight: false参数,让OPTIONS预检请求跳过默认授权校验,修改后配置如下:
Resources: ApiGateway: Type: AWS::Serverless::Api Properties: StageName: !Ref Stage Cors: "'*'" Auth: DefaultAuthorizer: MyCognitoAuthorizer # 新增下面这行配置 AddDefaultAuthorizerToCorsPreflight: false Authorizers: MyCognitoAuthorizer: UserPoolArn: !ImportValue UserPoolArn
- 你的业务Lambda函数(比如示例中的PutTodosFunction)需要在响应头中主动添加CORS相关字段,SAM的全局Cors配置只会自动给OPTIONS请求加响应头,业务请求的CORS头需要自行返回,Node.js环境下的响应示例如下:
exports.putItemHandler = async (event) => { // 你的业务逻辑代码 return { statusCode: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Methods': '*' }, body: JSON.stringify(yourResponseData) } }
- 修正前端请求代码,不需要主动发起OPTIONS请求,浏览器在跨域请求前会自动触发预检,直接发对应PUT/GET请求即可:
const headers = new Headers(); headers.append('Authorization', 'Bearer <替换为实际JWT令牌>'); fetch(API_URL, { headers, method: 'PUT', mode: 'cors' }) .then(console.log) .catch(console.log);
- 修改完成后重新部署SAM堆栈,确保API Gateway配置生效。
内容的提问来源于stack exchange,提问作者Jhecht
相关产品推荐
相关产品推荐

