AWS Custom Authorizer生成策略后超时,后续Lambda函数未执行求助
看起来你的问题核心出在async/await与Lambda callback的混用,再加上可能的超时配置不合理,结合你提供的日志和代码,我整理了几个关键修复步骤:
1. 停止在async授权器函数中使用callback
AWS Lambda对async函数的处理逻辑很明确:它会忽略callback调用,转而等待函数返回的Promise完成。如果你的授权器是async函数(因为你用了async/await获取业务信息),同时调用callback,Lambda会同时等待callback和Promise resolve,导致函数一直挂起直到超时。
修改你的授权器代码,直接返回授权结果而非依赖callback:
// 假设你的授权器函数是async类型 exports.company = async (event, context) => { // ... 你的业务信息获取逻辑(async/await部分) if (business) { const policy = generatePolicy(business, "Allow", event.methodArn); console.log("policy", policy.policyDocument.Statement); return policy; // 直接返回策略对象 } else { return generatePolicy(null, "Deny", event.methodArn); } };
2. 调整授权器Lambda的超时时间
从CloudWatch日志看,你的授权器在6秒后超时,说明当前超时配置是6秒。如果你的async/await操作(比如根据Authorization令牌获取业务信息的请求)耗时接近或超过这个阈值,就会触发超时。
在serverless.yml中增加授权器的超时配置:
companyAuth: handler: middleware/auth.company cors: true timeout: 10 # 根据实际业务耗时调整,比如设置为10秒
3. 修复generatePolicy函数的细节问题
你的generatePolicy函数里把principalId硬编码成了"Business",虽然这不会直接导致超时,但不符合自定义授权器的规范,建议改为使用传入的参数:
const generatePolicy = function(principalId, effect, resource) { const authResponse = {}; authResponse.principalId = principalId; // 替换硬编码的固定值 if (effect && resource) { const policyDocument = {}; policyDocument.Version = "2012-10-17"; policyDocument.Statement = []; const statementOne = {}; statementOne.Action = "execute-api:Invoke"; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; authResponse.context = { business: principalId }; } return authResponse; };
4. 确保异步操作的错误被正确捕获
如果你的async/await操作(获取业务信息)出现未捕获的错误,会导致Promise reject,async函数会返回一个rejected的Promise,Lambda会等待直到超时。一定要用try/catch包裹异步逻辑:
exports.company = async (event, context) => { try { const token = event.headers.Authorization; const business = await getBusinessInfo(token); // 你的异步获取逻辑 if (business) { const policy = generatePolicy(business, "Allow", event.methodArn); console.log("policy", policy.policyDocument.Statement); return policy; } else { return generatePolicy(null, "Deny", event.methodArn); } } catch (error) { console.error("Authorization error:", error); // 出错时返回拒绝策略 return generatePolicy(null, "Deny", event.methodArn); } };
至于本地serverless-offline正常的原因:本地模拟器对async函数和callback的混用处理更宽松,不会严格等待Promise完成,所以不会触发超时,但AWS官方Lambda环境会严格遵循异步函数的处理逻辑。
内容的提问来源于stack exchange,提问作者hanan hamza

