目标是按照User Pools App Integration and Federation中的描述实现社交提供者身份验证流程。
我想要满足的一件重要事情是合并具有相同电子邮件地址的用户池帐户。
我通过在PreSignUp_ExternalProvider cognito lambda触发器中调用adminLinkProviderForUser来实现这一目标。
因此,一切正常。新社交提供的用户正在注册并与现有的Cognito(用户+密码)用户链接。
但是,从用户的角度来看,身份验证流程尚未完成。它在调用回调uri(在cognito用户池中定义)的最后一步失败:
错误:invalid_request
error_description:已找到用户名Facebook_10155611263152353的条目
但是,如果用户重试社交身份验证流程,一切正常,并且会获得代表原始Cognito用户池用户(已经拥有该电子邮件的用户)的会话令牌。
请注意,我正在测试空用户池上的auth流,零用户帐户。
答案 0 :(得分:10)
对于所有在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>