【问题标题】:Change password using AWS.CognitoIdentityServiceProvider使用 AWS.CognitoIdentityServiceProvider 更改密码
【发布时间】:2023-03-07 00:26:02
【问题描述】:

我正在尝试弄清楚如何使用 AWS.CognitoIdentityServiceProvider 的 changePassword function

我需要将以下内容作为参数传递:

{
  PreviousPassword: 'STRING_VALUE', /* required */
  ProposedPassword: 'STRING_VALUE', /* required */
  AccessToken: 'STRING_VALUE'
}

我在 Lambda 函数中使用它,那么如何获取访问令牌?我有 cognitoIdentityPoolIdcognitoIdentityId 可以使用,但我不明白这个访问令牌是什么。

【问题讨论】:

    标签: amazon-web-services login access-token amazon-cognito


    【解决方案1】:

    因为没有管理员版本的 changePassword,您必须首先以您尝试影响的用户身份进行身份验证,然后才能调用 changePassword 例程。我花了很长时间才弄清楚这一点,似乎没有其他帖子涵盖您使用管理员调用和 UserPools 运行 NodeJS lambda 函数的情况,您希望支持“管理员”更改用户密码。我的(当前工作的)代码如下。请注意,我认为阻止管理员更改用户密码是 AWS 精心设计的决定,因此我不确定下面的解决方法将继续有效多长时间...

    const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
    
    
    // Accept a POST with a JSON structure containing the
    // refresh token provided during the original user login, 
    // and an old and new password.
    function changeUserPassword(event, context, callback) {
      // Extract relevant JSON into a request dict (This is my own utility code)
      let requiredFields = ['old_password','new_password','refresh_token'];
      let request = Utils.extractJSON(event['body'], requiredFields);
      if (request == false) {
        Utils.errorResponse("Invalid JSON or missing required fields", context.awsRequestId, callback);
        return; // Abort here
        }
    
    
      // This function can NOT be handled by admin APIs, so we need to
      // authenticate the user (not the admin) and use that
      // authentication instead.
      let refreshToken = request['refresh_token']
    
      // Authenticate as the user first, so we can call user version
      // of the ChangePassword API
      cognitoidentityserviceprovider.adminInitiateAuth({
        AuthFlow: 'REFRESH_TOKEN',
        ClientId: Config.ClientId,
        UserPoolId: Config.UserPoolId,
        AuthParameters: {
          'REFRESH_TOKEN': refreshToken
        },
        ContextData: getContextData(event)
      }, function(err, data) {
        if(err){
          Utils.errorResponse(err['message'], context.awsRequestId, callback);
          return // Abort here
        } else {
          // Now authenticated as user, change the password
          let accessToken = data['AuthenticationResult']['AccessToken'] // Returned from auth - diff signature than Authorization header
          let oldPass = request['old_password']
          let newPass = request['new_password']
          let params = {
            AccessToken: accessToken, /* required */
            PreviousPassword: oldPass, /* required */
            ProposedPassword: newPass /* required */
          }
    
          // At this point, really just a pass through
          cognitoidentityserviceprovider.changePassword(params, function(err2, data2) {
            if(err2){
              let message = {
                err_message: err2['message'],
                access_token: accessToken
              }
              Utils.errorResponse(message, context.awsRequestId, callback);
            } else {
              let response = {
                'success': 'OK',
                'response_data': data2 // Always seems to be empty
              }
              callback(response)
            }
          });
        }
      });
    
    }
    

    【讨论】:

    • 如何从 API 调用中执行登录?就我而言,我将 cognito 与 AWS ALB 一起使用。所以我在标头或 JWT 中都没有获得刷新令牌。
    • 建议您从 AWS 文档开始。这是一个服务器端的问题/答案,而不是客户端。见:docs.aws.amazon.com/cognito/latest/developerguide/…
    【解决方案2】:

    当您使用 AWS Lambda 时,您无需担心访问令牌,您只需将用户名和密码以及 poolID 传递给认知函数 adminSetUserPassword()。此函数将轻松更新密码

    const updateCognitoPassword = async(user_name, password) => {
        try {
            var changePasswordParams = {
                Password: password,
                Permanent: true,
                Username: user_name.trim(),
                UserPoolId: constants.user_pool_id
            };
            let data = await cognitoidentityserviceprovider.adminSetUserPassword(changePasswordParams).promise();
            return data;
        }
        catch (err) {
            throw new Error(err);
        }
    };
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。您可以使用edit 按钮改进此答案以获得更多选票和声誉!
    • 感谢 编辑了更多解释
    【解决方案3】:

    身份池 id 和身份 id 是 Cognito federated identities 的概念,而 ChangePassword API 是 user pools 的概念。它们是两种不同的服务 - 将用户池视为您的身份池的身份提供者。

    简短的版本是您可以通过使用用户池中的用户登录来获取访问令牌。这样做会返回访问令牌、id 令牌和刷新令牌。话虽如此,一个常见的主题是在 Lambda 端使用各种用户池 API 的管理员版本,因为那里可能没有用户凭据。

    【讨论】:

      【解决方案4】:

      我想用一个可以在 lambda 函数中使用的解决方案来扩展上面的一些答案,并展示如何设置所需的身份验证(使用 AWS 访问密钥和秘密访问密钥。

      这是一个创建为 lambda 的“更改密码”函数的工作示例。

      export async function  change_password (event, context, callback) {
        context.callbackWaitsForEmptyEventLoop = false;
        try {
          const { aws_cognito_id, newPassword } = JSON.parse(event.body)
          const cognitoIdentityService = new AWS.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18', region: '***AWS REGION GOES HERE***' });
          const userPoolId = "***COGNITO USER POOL ID GOES HERE***";
          const params = {
              Password: newPassword,
              Permanent: true,
              Username: aws_cognito_id,
              UserPoolId: userPoolId
          };
          AWS.config.region = '**AWS REGION**';
          cognitoIdentityService.config.update({ 
             accessKeyId: '***AWS ACCESS KEY***', 
             secretAccessKey: '***AWS SECRET ACCESS KEY***' 
          })
          let result = await cognitoIdentityService.adminSetUserPassword(params).promise();
          return generate_response(200, result)
        } catch (err) {
          return generate_error(500, err.message)
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-10
        • 2018-09-08
        • 2019-06-13
        • 2021-02-12
        • 2020-01-21
        • 2016-08-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多