在AWS Cognito中处理来自不同身份提供商(如Google和Facebook)的相同用户登录的最佳实践是使用联合身份。联合身份允许用户通过不同的身份提供商进行身份验证,并将它们关联到同一个用户。
以下是一个使用AWS SDK for JavaScript(Node.js)实现的示例代码:
const AWS = require('aws-sdk');
const cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
async function handleLogin(userEmail, identityProvider, identityToken) {
try {
// 检查用户是否已经存在于Cognito User Pool
const existingUser = await getUserByEmail(userEmail);
if (existingUser) {
// 用户已存在,将身份提供商和身份令牌添加到现有用户的身份验证中
await linkIdentities(existingUser.Username, identityProvider, identityToken);
// 返回现有用户的Cognito身份ID
return existingUser.Username;
} else {
// 用户不存在,创建一个新用户
const newUser = await createUser(userEmail, identityProvider, identityToken);
// 返回新用户的Cognito身份ID
return newUser.User.Username;
}
} catch (error) {
console.error('Error handling login:', error);
throw error;
}
}
async function getUserByEmail(email) {
const params = {
UserPoolId: 'YOUR_USER_POOL_ID',
Filter: `email = "${email}"`,
Limit: 1
};
const response = await cognitoIdentityServiceProvider.listUsers(params).promise();
if (response.Users.length > 0) {
return response.Users[0];
} else {
return null;
}
}
async function linkIdentities(cognitoUsername, identityProvider, identityToken) {
const params = {
SourceUserIdentifier: cognitoUsername,
DestinationUserIdentifier: identityToken,
IdentityProviderName: identityProvider,
UserPoolId: 'YOUR_USER_POOL_ID'
};
await cognitoIdentityServiceProvider.adminLinkProviderForUser(params).promise();
}
async function createUser(email, identityProvider, identityToken) {
const params = {
UserPoolId: 'YOUR_USER_POOL_ID',
Username: email,
UserAttributes: [
{
Name: 'email',
Value: email
}
],
TemporaryPassword: 'TEMPORARY_PASSWORD',
MessageAction: 'SUPPRESS',
DesiredDeliveryMediums: ['EMAIL'],
ForceAliasCreation: false
};
const newUser = await cognitoIdentityServiceProvider.adminCreateUser(params).promise();
// 将身份提供商和身份令牌添加到新用户的身份验证中
await linkIdentities(newUser.User.Username, identityProvider, identityToken);
return newUser;
}
注意替换示例代码中的YOUR_USER_POOL_ID,并根据需要进行其他自定义。此示例仅涵盖了基本的登录处理逻辑,您可能需要根据您的需求进行调整和扩展。