AWS Cognito - 用户卡在 CONFIRMED 和 email_verified = false
AWS Cognito - User stuck in CONFIRMED and email_verified = false
如何通过电子邮件验证已确认但 email_verified 为假的用户?
场景大致是一个代理代表他们注册用户,我通过管理员调用 adminConfirmSignUp 确认用户。此时,由于 email_verified 标志为假,用户无法更改密码。
我无法调用 resendConfirmationCode,因为用户已经确认。
我无法调用 forgotPassword,因为 email_verified 标志是错误的。
我能想到的最好的办法是删除用户帐户并调用注册(提示他们重新输入密码或新密码),从而重新创建他们的帐户。
目前,Cognito 不允许外部代理代表用户更新 email_verified 和 phone_verified 属性。将这些标记为 true 的唯一方法是通过最终用户可以完成的代码验证过程。例外情况是管理员级别 APIs,如下面的答案所述,但不应从客户端完成。
过程是这样的:用户登录并获取访问令牌。然后,他们使用要验证的属性调用 GetUserAttrbuteVerificationCode API。这将向用户提供一个代码,可以通过调用 VerifyUserAttribute 来使用,这会将属性翻转为已验证。
您现在可以使用预注册 lambda 触发器以编程方式将 email_verified
设置为 true,并使用 event.response.autoVerifyEmail = true;
修改返回的事件
它还没有在文档中,但是 referenced on this github issue. Also read working with cognito lambda triggers。
您可以通过不使用任何 lambda 和触发器调用 adminUpdateUserAttributes
来更改 email_verified
、phone_number_verified
和其他属性:
'use strict'
var AWS = require('aws-sdk')
AWS.config.update({
accessKeyId: 'YOUR_ACCESS_KEY_HERE',
secretAccessKey: 'YOUR_SECRET_ACCESS_KEY_HERE',
region: 'us-east-1' // change region if required
});
var CognitoIdentityServiceProvider = AWS.CognitoIdentityServiceProvider
var client = new CognitoIdentityServiceProvider({
apiVersion: '2016-04-19',
region: 'us-east-1' // change region if required
})
client.adminUpdateUserAttributes({
UserAttributes: [{
Name: 'phone_number_verified',
Value: 'true'
}, {
Name: 'email_verified',
Value: 'true'
}
// other user attributes like phone_number or email themselves, etc
],
UserPoolId: 'COGNITO_USER_POOL_ID_HERE',
Username: 'USERNAME'
}, function(err) {
if (err) {
console.log(err, err.stack)
} else {
console.log('Success!')
}
})
使用 AWS CLI,您可以更新 email_verified 属性:
aws cognito-idp admin-update-user-attributes
--user-pool-id eu-west-xxxxxx
--username xxxxyyyy@example.com
--user-attributes Name=email_verified,Value=true
Trigger on pre-registration 这个 lambda 函数 (Node.js v6):
exports.handler = function(event, context) {
event.response.autoConfirmUser = true;
event.response.autoVerifyEmail = true;
event.response.autoVerifyPhone = true;
context.done(null, event);
};
使用 "Configure test event" 你可以先用这个 payload 测试它
{
"version": 1,
"triggerSource": "PreSignUp_SignUp",
"region": "<region>",
"userPoolId": "<userPoolId>",
"userName": "<userName>",
"callerContext": {
"awsSdk": "<calling aws sdk with version>",
"clientId": "<apps client id>"
},
"request": {
"userAttributes": {
"email": "usertestsns06@yopmail.com"
},
"validationData": {
"k1": "v1",
"k2": "v2"
}
},
"response": {
"autoConfirmUser": false,
"autoVerifyEmail": false,
"autoVerifyPhone": false
}
}
现在,当您从 API 创建用户时,那些验证标志应该是 true
。
使用 boto3
使用 python 在 aws cognito 上验证用户电子邮件
响应=client.get_user_attribute_verification_code(AccessToken='eyJraWQiOiJtTEM4Vm......',AttributeName='email')
response = client.verify_user_attribute(AccessToken='eyJraWQiOiJtTEM......', AttributeName='email', Code='230433')
这是官方文档。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html
这是您可以用来通过代理创建用户的另一种方法。
您可以代表用户使用 AdminCreateUser。通过调用此 API 用户将创建一个临时密码,该密码将发送到用户电子邮件地址。 (即用户将处于 Force_Change_Password 状态)。现在使用 RespondToAuthChallenge API 更改密码。
注意:您需要在属性列表中设置"email_verified"属性。以确保验证用户电子邮件。
这是 NodeJS 中的代码示例:
var params = {
UserPoolId: process.env.userPoolId, /* required */
Username: email,//'STRING_VALUE', /* required */
DesiredDeliveryMediums: [
"EMAIL",
/* more items */
],
ForceAliasCreation: false,
UserAttributes: [{
Name: 'email_verified',
Value: 'True'
},/* any other Attributes*/],
};
cognitoidentityserviceprovider.adminCreateUser(params, function (err, data) {
if (err) {
console.log(err, err.stack);
reject(err); // an error occurred
}
else {
console.log(data);
resolve(data);
}// successful response
});
});
给出错误信息:'No email provided but email_verified was true',代码:'InvalidParameterException'。
所以我也将电子邮件属性添加到属性列表中。
const params = {
UserPoolId: this.userPoolId /* required */,
Username: username /* required */,
TemporaryPassword: password,
DesiredDeliveryMediums: ['EMAIL'],
ForceAliasCreation: false,
UserAttributes: [
{
Name: 'email_verified' /* required */,
Value: 'true',
},
{
Name: 'email' /* required */,
Value: email,
},
],
};
然后使用这些参数创建用户
cognitoidentityserviceprovider.adminCreateUser(
params,
(err, data) => {
console.log(data);
if (err) {
console.log(err);
reject(err);
throw new BadRequestException(err);
}
// an error occurred
else resolve(data); // successful response
},
);
如何通过电子邮件验证已确认但 email_verified 为假的用户?
场景大致是一个代理代表他们注册用户,我通过管理员调用 adminConfirmSignUp 确认用户。此时,由于 email_verified 标志为假,用户无法更改密码。
我无法调用 resendConfirmationCode,因为用户已经确认。
我无法调用 forgotPassword,因为 email_verified 标志是错误的。
我能想到的最好的办法是删除用户帐户并调用注册(提示他们重新输入密码或新密码),从而重新创建他们的帐户。
目前,Cognito 不允许外部代理代表用户更新 email_verified 和 phone_verified 属性。将这些标记为 true 的唯一方法是通过最终用户可以完成的代码验证过程。例外情况是管理员级别 APIs,如下面的答案所述,但不应从客户端完成。
过程是这样的:用户登录并获取访问令牌。然后,他们使用要验证的属性调用 GetUserAttrbuteVerificationCode API。这将向用户提供一个代码,可以通过调用 VerifyUserAttribute 来使用,这会将属性翻转为已验证。
您现在可以使用预注册 lambda 触发器以编程方式将 email_verified
设置为 true,并使用 event.response.autoVerifyEmail = true;
它还没有在文档中,但是 referenced on this github issue. Also read working with cognito lambda triggers。
您可以通过不使用任何 lambda 和触发器调用 adminUpdateUserAttributes
来更改 email_verified
、phone_number_verified
和其他属性:
'use strict'
var AWS = require('aws-sdk')
AWS.config.update({
accessKeyId: 'YOUR_ACCESS_KEY_HERE',
secretAccessKey: 'YOUR_SECRET_ACCESS_KEY_HERE',
region: 'us-east-1' // change region if required
});
var CognitoIdentityServiceProvider = AWS.CognitoIdentityServiceProvider
var client = new CognitoIdentityServiceProvider({
apiVersion: '2016-04-19',
region: 'us-east-1' // change region if required
})
client.adminUpdateUserAttributes({
UserAttributes: [{
Name: 'phone_number_verified',
Value: 'true'
}, {
Name: 'email_verified',
Value: 'true'
}
// other user attributes like phone_number or email themselves, etc
],
UserPoolId: 'COGNITO_USER_POOL_ID_HERE',
Username: 'USERNAME'
}, function(err) {
if (err) {
console.log(err, err.stack)
} else {
console.log('Success!')
}
})
使用 AWS CLI,您可以更新 email_verified 属性:
aws cognito-idp admin-update-user-attributes
--user-pool-id eu-west-xxxxxx
--username xxxxyyyy@example.com
--user-attributes Name=email_verified,Value=true
Trigger on pre-registration 这个 lambda 函数 (Node.js v6):
exports.handler = function(event, context) {
event.response.autoConfirmUser = true;
event.response.autoVerifyEmail = true;
event.response.autoVerifyPhone = true;
context.done(null, event);
};
使用 "Configure test event" 你可以先用这个 payload 测试它
{
"version": 1,
"triggerSource": "PreSignUp_SignUp",
"region": "<region>",
"userPoolId": "<userPoolId>",
"userName": "<userName>",
"callerContext": {
"awsSdk": "<calling aws sdk with version>",
"clientId": "<apps client id>"
},
"request": {
"userAttributes": {
"email": "usertestsns06@yopmail.com"
},
"validationData": {
"k1": "v1",
"k2": "v2"
}
},
"response": {
"autoConfirmUser": false,
"autoVerifyEmail": false,
"autoVerifyPhone": false
}
}
现在,当您从 API 创建用户时,那些验证标志应该是 true
。
使用 boto3
使用 python 在 aws cognito 上验证用户电子邮件响应=client.get_user_attribute_verification_code(AccessToken='eyJraWQiOiJtTEM4Vm......',AttributeName='email')
response = client.verify_user_attribute(AccessToken='eyJraWQiOiJtTEM......', AttributeName='email', Code='230433')
这是官方文档。 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html
这是您可以用来通过代理创建用户的另一种方法。 您可以代表用户使用 AdminCreateUser。通过调用此 API 用户将创建一个临时密码,该密码将发送到用户电子邮件地址。 (即用户将处于 Force_Change_Password 状态)。现在使用 RespondToAuthChallenge API 更改密码。
注意:您需要在属性列表中设置"email_verified"属性。以确保验证用户电子邮件。
这是 NodeJS 中的代码示例:
var params = {
UserPoolId: process.env.userPoolId, /* required */
Username: email,//'STRING_VALUE', /* required */
DesiredDeliveryMediums: [
"EMAIL",
/* more items */
],
ForceAliasCreation: false,
UserAttributes: [{
Name: 'email_verified',
Value: 'True'
},/* any other Attributes*/],
};
cognitoidentityserviceprovider.adminCreateUser(params, function (err, data) {
if (err) {
console.log(err, err.stack);
reject(err); // an error occurred
}
else {
console.log(data);
resolve(data);
}// successful response
});
});
给出错误信息:'No email provided but email_verified was true',代码:'InvalidParameterException'。
所以我也将电子邮件属性添加到属性列表中。
const params = {
UserPoolId: this.userPoolId /* required */,
Username: username /* required */,
TemporaryPassword: password,
DesiredDeliveryMediums: ['EMAIL'],
ForceAliasCreation: false,
UserAttributes: [
{
Name: 'email_verified' /* required */,
Value: 'true',
},
{
Name: 'email' /* required */,
Value: email,
},
],
};
然后使用这些参数创建用户
cognitoidentityserviceprovider.adminCreateUser(
params,
(err, data) => {
console.log(data);
if (err) {
console.log(err);
reject(err);
throw new BadRequestException(err);
}
// an error occurred
else resolve(data); // successful response
},
);