AWS Serverless自定义授权器本地返回401部署后始终返回500问题
故障根因
- 当前Serverless配置的自定义授权器未显式指定token来源,默认取
AuthorizationToken请求头,而客户端常规是传Authorization请求头,导致代码中取event.authorizationToken为空。 - 你使用的async类型handler在调用callback返回401后没有return,后续代码执行
token.includes('Bearer ')时,token为undefined触发类型错误,错误被catch捕获后直接透传给API Gateway,最终返回500。 - 本地测试时你是直接模拟event参数传入
authorizationToken字段,不会触发该缺陷,所以本地表现正常。
解决方案
方案一(推荐,符合通用规范):调整Serverless配置
在http事件的authorizer配置中补充type和identitySource字段,指定授权器从标准Authorization请求头取token:
shareImage: handler: src/app/handlers/shareImageHandler.handler vpc: ${self:custom.vpc.private} events: - http: path: /shareImage method: post authorizer: name: authorizerFunc type: token identitySource: method.request.header.Authorization resultTtlInSeconds: 0
配置后API Gateway会自动把Authorization请求头的值填入event.authorizationToken字段传递给授权器函数。
方案二:修复代码逻辑
无论是否调整配置,都需要修复handler的逻辑缺陷,避免运行时错误导致500:
module.exports.handler = async (event: any, context: Context, callback: Callback) : Promise<any> => { try { // 可选兼容逻辑:同时从两个位置取token,适配不同场景 let token: string = event.authorizationToken || event.headers?.Authorization; if (!token) { callback(new HttpError(401,'Unauthorized'), null); return; // 调用callback后必须return,终止后续代码执行 } // 去除Bearer前缀 if (token.includes('Bearer ')) { token = token.substring(7, token.length); } // 验证token有效性 const cognitoUserId = await verifyUserToken(token) if (!cognitoUserId) { callback(new HttpError(401,'Unauthorized'), null); return; // 调用callback后必须return } callback(null, generatePolicy('user', 'Allow', event.methodArn, cognitoUserId)); } catch (e) { console.error('Error authorizing user', e); // 捕获所有异常统一返回401,避免透传错误导致500 callback(new HttpError(401,'Unauthorized'), null); } }
调整后重新部署即可解决500错误,未授权场景会正常返回401。
内容的提问来源于stack exchange,提问作者Tomer
相关产品推荐
相关产品推荐

