Cognito auth流程失败,“已找到用户名Facebook_10155611263153532的条目”

时间:2017-12-14 14:00:11

标签: amazon-web-services oauth-2.0 amazon-cognito amazon-cognito-facebook

目标是按照User Pools App Integration and Federation中的描述实现社交提供者身份验证流程。

我想要满足的一件重要事情是合并具有相同电子邮件地址的用户池帐户。

我通过在PreSignUp_ExternalProvider cognito lambda触发器中调用adminLinkProviderForUser来实现这一目标。

因此,一切正常。新社交提供的用户正在注册并与现有的Cognito(用户+密码)用户链接。

但是,从用户的角度来看,身份验证流程尚未完成。它在调用回调uri(在cognito用户池中定义)的最后一步失败:

  

错误:invalid_request

     

error_description:已找到用户名Facebook_10155611263152353的条目

但是,如果用户重试社交身份验证流程,一切正常,并且会获得代表原始Cognito用户池用户(已经拥有该电子邮件的用户)的会话令牌。

请注意,我正在测试空用户池上的auth流,零用户帐户。

4 个答案:

答案 0 :(得分:10)

对于所有在2020年仍在与这个问题作斗争的可怜人,我都这样做:

  • 我最终通过在客户端应用程序中捕获“已找到用户名条目”并再次重复整个身份验证流程来解决此问题。
  • 幸运的是,该错误仅在初始外部提供程序注册时触发,而在同一用户的后续登录中不触发(因为它在注册触发期间发生)。 我正在做出一个疯狂的猜测,但这是我正在发生的事情:
    • 就我而言,facebook提供商已成功与链接 先前存在的认知电子邮件/密码用户。新的Facebook用户池 链接到电子邮件/密码用户的条目已成功创建。
    • 似乎 像cognito一样尝试注册完全孤立的Facebook_id用户 在内部注册过程中(即使在上一步中已经创建了具有相同用户名的链接用户条目)。由于“链接用户”与 用户名Facebook_id已经存在,cognito抛出了一个 内部错误:“已找到用户名Facebook_id错误条目”。
    • 自2017年以来,这个错误已经多次被告知AWS开发人员,甚至他们的工作都得到了一些回应,但是到2020年,它仍然没有得到解决。

答案 1 :(得分:0)

是的,这就是目前的设置方式。如果您尝试使用PreSignUp触发器链接用户,则第一次将无效。处理此问题的更好方法(我认为)是在您的UI中提供一个选项,以便在登录时链接外部帐户。在预注册触发器中,搜索具有相同唯一属性(例如电子邮件)的用户,并查看注册是否来自外部提供商。然后显示已存在的电子邮件等消息。登录&使用此菜单/选项进行链接。虽然没有测试过这个。

答案 2 :(得分:0)

要详细说明@ agent420的答案,这是我当前正在使用的(打字稿示例)。

当社交身份尝试注册且电子邮件地址已经存在时,我使用PreSignUp触发器捕获了此电子邮件,然后将错误消息返回给用户。在应用程序内部,在用户的个人资料页面上,有一个选项可以链接一个调用adminLinkProviderForUser API的身份提供程序。

import {
    Context,
    CognitoUserPoolTriggerEvent,
    CognitoUserPoolTriggerHandler,
} from 'aws-lambda';
import * as aws from 'aws-sdk';
import { noTryAsync } from 'no-try';

export const handle: CognitoUserPoolTriggerHandler = async (
    event: CognitoUserPoolTriggerEvent,
    context: Context,
    callback: (err, event: CognitoUserPoolTriggerEvent) => void,
): Promise<any> => {
    context.callbackWaitsForEmptyEventLoop = false;

    const { email } = event.request.userAttributes;

    // pre sign up with external provider
    if (event.triggerSource === 'PreSignUp_ExternalProvider') {
        // check if a user with the email address already exists

        const sp = new aws.CognitoIdentityServiceProvider();

        const { error } = await noTryAsync(() =>
            sp
                .adminGetUser({
                    UserPoolId: 'your-user-pool-id',
                    Username: email,
                })
                .promise(),
        );

        if (error && !(error instanceof aws.AWSError)) {
            throw error;
        } else if (error instanceof aws.AWSError && error.code !== 'UserNotFoundException') {
            throw error;
        }
    }

    callback(null, event);
};

答案 3 :(得分:0)

已调用JavaScript getUser中的相同代码,而不是listUsers。还假定所有用户都将其电子邮件ID作为用户名。

<main>
  <div class="wrapper">
    <h1>Rock, Paper, Scissors!</h1>
    <h3>Instructions:</h3>
    <p>You will be playing against the computer. There will be a total of 3 rounds. Good luck!</p>
    <h2 id="choose">Choose:</h2>
  </div>
  <div class="container">
    <button>
      <img id="rock" src="https://static.thenounproject.com/png/477914-200.png">
    </button>
  </div>
  <div class="results">
    <p class='computerSelection'></p>
    <p class='result'></p>
    <p class='computerScore'></p>
    <p class='playerScore'><span></span></p>
    <p class='finalResult'></p>
  </div>
</main>