【问题标题】:adminuserglobalsignout not returning any data or not awaiting promiseadminuserglobalsignout 不返回任何数据或不等待承诺
【发布时间】:2019-10-21 10:55:29
【问题描述】:

当由于 adminuserglobalsignout 等待承诺时,承诺似乎返回,但数据不包含任何内容。

注销后的下一个调用是对用户进行身份验证。返回了正确的 accessToken 但它已经被撤销了,这让我认为承诺没有正确等待,并且新凭据正在被仍在运行的前一个调用注销。

我们正在使用 globalsignout 来防止用户拥有多个会话,因此工作流程遵循以下原则

验证 -> 成功 -> 注销(终止任何其他会话)-> 验证 -> 成功 -> 返回令牌

我已更新我的 lambda 包以包含最新的 SDK 版本 2.469.0,但没有任何改进。

有时时间必须没问题,因为返回的凭据仍然有效并且可以使用令牌。

在这两种情况下,AWS 调用返回的数据似乎为零

调用用户库中的注销方法的 lambda 代码部分

    try {

        signOutResult = await User.globalSignOut(userId, process.env.COGNITO_POOL);

    } catch (err) {

        log.error("AWS Global Signout Error: " + JSON.stringify(err));
        responseBody = Helper.buildCORSResponse(502, JSON.stringify({ message: err }));

        return callback(null, responseBody);

    }

用户库中的全局注销代码:


    return new Promise((resolve, reject) => {

        log.info(`globalSignOut: Signing ${Username} out from all devices in pool ${UserPoolId}`);

        const signOutRequest = new AWS.CognitoIdentityServiceProvider({ apiVersion: "2016-04-18" }).adminUserGlobalSignOut({ Username, UserPoolId });
        const signOutPromise = signOutRequest.promise();

        signOutPromise.
            then((data) => {

                log.debug("globalSignOut: Cognito SignOut Success: " + JSON.stringify(data));
                resolve(data);

            }).catch((err) => {

                log.error("globalSignOut: Cognito SignOut Error: " + err);
                reject(err);

            });

    });

}

在每次调用中,我们都会毫无问题地解决问题,然后我们会再次对用户进行身份验证。

            log.debug("globalSignOut: Cognito SignOut Success: " + JSON.stringify(data));
            resolve(data);

有没有人发现任何可能导致这种情况的问题?我尝试了几种方法来指定承诺,并使用适用于其他服务的相同格式并在代码执行继续之前等待结果的承诺。

非常感谢所有建议

【问题讨论】:

  • 脏黑客警告。在解决 promise 之前添加了一个 sleep 函数,你会发现收到的每组令牌都是有效的。必须与 AWS 方法如何提前返回我的代码有关,或者我相信我正在正确地等待 AWS 的预期承诺。

标签: javascript aws-lambda aws-sdk amazon-cognito


【解决方案1】:

从 AWS Support 更新此行为,以防其他人发现此问题。我可以确认,在全局注销后重新验证用户身份之前添加一小段延迟可以正常工作。

感谢您回复我们。

为了解决这个问题,我尝试通过测试下面提到的流程(由您在 中提供)来复制它:

验证用户->全局注销->再次验证-->检查新令牌的有效性

我写了一个python代码来实现上面的流程。在流程中,调用 globalSignOut 方法后,我再次对用户进行身份验证,并通过调用 getUser API 来检查令牌的有效性。但是,getUser API 调用返回以下响应:“调用 GetUser 操作时发生错误 (NotAuthorizedException):访问令牌已被撤销”

现在,我在 GlobalSignOut 1 秒后添加了睡眠功能,并且流程正常工作。我对睡眠时间做了一些测试,发现如果我们添加 0.6 秒或更长的睡眠时间,API 就可以正常工作。因此,看起来 GlobalSignOut API 调用立即返回响应,但全局注销过程(撤销令牌)仍然在后端运行大约 0.6 秒。

为此,我联系了 Cognito 开发团队以确认 GlobalSignOut API 调用的这种行为。团队已确认这是 GlobalSignOut API 调用的预期行为。当调用 GlobalSignOut 时,在该时间之前发布的所有令牌都被视为无效。如果注销和身份验证之间的差距非常小(根据我的测试,这大约是 0.6 秒),则可以将身份验证后的令牌问题视为在注销调用之前发出,并且为了更好的安全性,将其视为无效。

希望以上信息对您有所帮助。如果还有什么我可以帮忙的,请告诉我。我很乐意为您提供帮助。

祝你有美好的一天。

最好的问候,

亚马逊网络服务

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 2017-02-03
    • 2019-10-20
    • 2018-06-04
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多