You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Amplify:自定义UI场景下忘记密码功能实现问题咨询

解决Cognito忘记密码流程中通过邮箱获取用户名的问题

首先得澄清一个误解:Cognito并不会默认哈希存储邮箱地址——你看到的“唯一哈希值”大概率是用户的sub(Cognito分配的唯一用户标识符),而不是邮箱或者用户名。如果管理员是在AWS控制台注册用户时,把邮箱设置为用户名,那用户名就是明文的邮箱地址;如果用户名是其他值,邮箱只是用户属性,那这个属性也是可以被检索到的。

接下来分两种场景给你具体的实现方案:

场景1:用户名就是邮箱地址

这是最直接的情况,你完全不需要额外获取用户名,因为用户输入的邮箱本身就是Cognito的用户名。直接用Amplify的Auth.forgotPassword()方法即可触发密码重置流程:

async function handlePasswordResetRequest(email) {
  try {
    // 直接传入用户输入的邮箱(即用户名)
    await Auth.forgotPassword(email);
    // 执行到这里,Cognito已经向该邮箱发送了验证码
    alert("密码重置验证码已发送至你的邮箱,请查收");
  } catch (error) {
    console.error("重置请求失败:", error);
    if (error.code === 'UserNotFoundException') {
      alert("该邮箱对应的账号不存在");
    } else {
      alert("请求失败,请稍后重试");
    }
  }
}

调用这个方法后,Cognito会自动验证该用户名(邮箱)是否存在,存在的话就发送验证码到用户邮箱,之后你可以引导用户输入验证码和新密码,调用Auth.forgotPasswordSubmit()完成重置。

场景2:用户名≠邮箱,邮箱是用户属性

这种情况下,普通前端用户没有权限直接搜索Cognito用户列表,所以需要借助后端服务(比如AWS Lambda)来完成“通过邮箱找用户名”的操作,再触发密码重置:

步骤1:创建Lambda函数(后端处理逻辑)

这个Lambda需要有Cognito的ListUsers和AdminForgotPassword权限,代码示例(Node.js):

const AWS = require('aws-sdk');
const cognitoISP = new AWS.CognitoIdentityServiceProvider();

exports.handler = async (event) => {
  const { email } = JSON.parse(event.body);
  const USER_POOL_ID = "你的Cognito用户池ID";

  try {
    // 搜索邮箱匹配的用户
    const searchParams = {
      UserPoolId: USER_POOL_ID,
      Filter: `email = "${email}"`,
      Limit: 1 // 只取第一个匹配的用户(避免重复邮箱)
    };
    const searchResult = await cognitoISP.listUsers(searchParams).promise();

    if (searchResult.Users.length === 0) {
      return {
        statusCode: 404,
        body: JSON.stringify({ message: "该邮箱对应的账号不存在" })
      };
    }

    const targetUsername = searchResult.Users[0].Username;
    // 触发管理员发起的密码重置
    await cognitoISP.adminForgotPassword({
      UserPoolId: USER_POOL_ID,
      Username: targetUsername
    }).promise();

    return {
      statusCode: 200,
      body: JSON.stringify({ message: "密码重置验证码已发送至你的邮箱" })
    };
  } catch (err) {
    console.error("处理请求出错:", err);
    return {
      statusCode: 500,
      body: JSON.stringify({ message: "服务器内部错误" })
    };
  }
};

步骤2:前端调用Lambda(通过API Gateway)

把上面的Lambda配置到API Gateway后,前端可以通过HTTP请求调用:

async function handlePasswordResetRequest(email) {
  try {
    const response = await fetch("你的API Gateway端点URL", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email })
    });
    const result = await response.json();
    alert(result.message);
  } catch (err) {
    console.error("请求失败:", err);
    alert("请求出错,请稍后重试");
  }
}

补充说明

你之前查看的Amplify Auth代码之所以假设已有用户名,是因为forgotPassword方法本身就是设计为接收用户名参数的——如果你的用户名就是邮箱,那直接用邮箱作为参数就完全符合这个设计,不需要额外处理。

内容的提问来源于stack exchange,提问作者Fesch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:45:59