You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Cognito listUsers方法调用后回调函数未执行问题

AWS Lambda中Cognito listUsers回调不执行问题

问题背景

当前正在学习AWS相关服务,基于API Gateway + Cognito Authorizer实现用户身份认证,目前认证模块已运行正常:可正常生成令牌返回前端,也能正常接收前端回传至API的合法令牌。
后续需要从Cognito用户池中拉取指定用户属性,存入DynamoDB的非规范化字段中,经评估在POST请求处理阶段拉取用户属性是较合理的实现方式,该操作需要调用cognitoidentityserviceprovider.listUsers方法。
遇到的问题:该方法的回调函数始终不会执行。最初调用时返回未授权错误,更新对应IAM策略后该错误已消除,但目前仅能打印回调函数外部的日志,回调函数内部的日志完全无法输出。

相关代码片段

let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});

let sub = event.requestContext.authorizer.claims.sub;
let userpool = event.stageVariables.userpool;

const cogParams = {
 UserPoolId: userpool,
 Filter: "sub=\""+ sub + "\"",
 Limit: 1
};

console.log('listing',JSON.stringify(cogParams));

cognitoidentityserviceprovider.listUsers(cogParams, function(err, data) {
    console.info('entered callback');
    if (err) {
        console.log(err, err.stack); 
    } else {
        console.log('data',data);
    }
    console.info('end callback');
});

console.log('listed');

日志输出对比

预期日志输出

listing {...}
entered callback
data {...}
end callback
listed

实际运行输出

listing {...}
listed

问题原因

该问题是Lambda Node.js运行时的执行机制导致的:Lambda会在主处理函数逻辑执行完成、返回响应后立刻冻结执行环境,不会等待事件循环中未完成的异步任务执行。当前代码调用listUsers发起异步请求后,没有等待请求返回就继续执行完了主流程的所有逻辑、提前返回,导致异步回调根本没有机会被执行。

解决方案

  • 优先使用async/await搭配AWS SDK的Promise模式处理异步请求,确保所有异步操作执行完成后再结束主函数逻辑,参考修正代码:
// Lambda处理函数需要添加async关键字
exports.handler = async (event) => {
    const AWS = require('aws-sdk');
    let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});

    let sub = event.requestContext.authorizer.claims.sub;
    let userpool = event.stageVariables.userpool;

    const cogParams = {
        UserPoolId: userpool,
        Filter: `sub="${sub}"`,
        Limit: 1
    };

    console.log('listing',JSON.stringify(cogParams));
    // 等待listUsers请求完成
    const userData = await cognitoidentityserviceprovider.listUsers(cogParams).promise();
    console.log('entered callback');
    console.log('data', userData);
    console.log('end callback');

    // 后续写入DynamoDB、构造API响应的逻辑全部放在await之后
    console.log('listed');
    return {
        statusCode: 200,
        body: JSON.stringify({message: 'success'})
    }
}
  • 如果要保留回调写法,必须把所有后续业务逻辑(包括给API Gateway返回响应的操作)全部放到listUsers的回调函数内部,确保回调执行完成前主函数不会返回。

优化建议

不需要额外调用listUsers拉取用户属性:Cognito Authorizer校验令牌通过后,会自动把ID Token中包含的所有用户属性解析到event.requestContext.authorizer.claims对象中,常用的sub、邮箱、用户名以及自定义属性只要存在于令牌中,可直接从该对象读取,能省掉一次Cognito API调用,降低接口延迟。如果需要的属性没有出现在claims中,可以到Cognito用户池的应用客户端配置页,把对应属性加入ID令牌的返回声明列表即可。

内容的提问来源于stack exchange,提问作者meteorainer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:24:30