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_verifiedphone_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

官方文档如下:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cognito-idp/admin-update-user-attributes.html

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
    },
  );