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

如何用AWS IAM与JavaScript SDK构建登录?含Cognito对比及代码示例需求

最佳方案选择:AWS Cognito vs IAM+STS

为什么优先选Cognito?

  • 专门面向终端用户身份管理:内置用户注册、登录、密码重置、MFA、社交登录(Google/Facebook)等功能,无需从零开发
  • 安全合规:自动处理凭证轮换、密码哈希、防暴力破解,符合OAuth2.0、OpenID Connect标准
  • 与AWS服务无缝集成:通过身份池(Identity Pool)可以直接给用户颁发访问AWS资源的临时凭证,无需手动调用STS
  • 无IAM用户数量限制:IAM默认仅支持5000个用户,Cognito用户池可支持百万级用户

如果一定要用IAM+STS实现(不推荐)

核心逻辑

  • 注册:为每个用户创建IAM用户(注意:IAM用户是AWS账户级身份,不适合大量终端用户)
  • 认证:用户提供IAM用户名密码,后端验证后调用STS AssumeRole生成临时凭证
  • 授权:通过IAM角色的权限策略控制用户能访问的AWS资源

潜在问题

  • 管理成本高:需自行实现密码管理、MFA、用户生命周期(禁用/删除)
  • 安全风险:IAM用户默认是长期凭证,若泄露会直接威胁AWS账户安全
  • 数量限制:IAM用户数量上限默认5000,无法支撑大规模用户

示例代码

1. AWS Cognito 示例(Node.js)

依赖安装

npm install @aws-sdk/client-cognito-identity-provider @aws-sdk/client-cognito-identity

用户注册

const { CognitoIdentityProviderClient, SignUpCommand } = require("@aws-sdk/client-cognito-identity-provider");

const client = new CognitoIdentityProviderClient({ region: "us-east-1" });

async function signUp(username, password, email) {
  const command = new SignUpCommand({
    ClientId: "YOUR_COGNITO_APP_CLIENT_ID",
    Username: username,
    Password: password,
    UserAttributes: [
      { Name: "email", Value: email }
    ]
  });

  try {
    const response = await client.send(command);
    console.log("注册成功:", response.UserSub);
    return response;
  } catch (error) {
    console.error("注册失败:", error);
    throw error;
  }
}

// 调用示例
signUp("test-user", "StrongPassword123!", "test@example.com");

用户登录并获取AWS资源访问凭证

const { CognitoIdentityProviderClient, InitiateAuthCommand } = require("@aws-sdk/client-cognito-identity-provider");
const { CognitoIdentityClient, GetIdCommand, GetCredentialsForIdentityCommand } = require("@aws-sdk/client-cognito-identity");

const cognitoIdpClient = new CognitoIdentityProviderClient({ region: "us-east-1" });
const cognitoIdentityClient = new CognitoIdentityClient({ region: "us-east-1" });

async function loginAndGetCredentials(username, password) {
  // 1. 用户登录获取ID Token
  const authCommand = new InitiateAuthCommand({
    ClientId: "YOUR_COGNITO_APP_CLIENT_ID",
    AuthFlow: "USER_PASSWORD_AUTH",
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password
    }
  });

  const authResponse = await cognitoIdpClient.send(authCommand);
  const idToken = authResponse.AuthenticationResult.IdToken;

  // 2. 通过ID Token获取Cognito Identity ID
  const getIdCommand = new GetIdCommand({
    IdentityPoolId: "YOUR_COGNITO_IDENTITY_POOL_ID",
    Logins: {
      [`cognito-idp.us-east-1.amazonaws.com/YOUR_COGNITO_USER_POOL_ID`]: idToken
    }
  });

  const getIdResponse = await cognitoIdentityClient.send(getIdCommand);
  const identityId = getIdResponse.IdentityId;

  // 3. 获取访问AWS资源的临时凭证
  const getCredsCommand = new GetCredentialsForIdentityCommand({
    IdentityId: identityId,
    Logins: {
      [`cognito-idp.us-east-1.amazonaws.com/YOUR_COGNITO_USER_POOL_ID`]: idToken
    }
  });

  const credsResponse = await cognitoIdentityClient.send(getCredsCommand);
  console.log("临时凭证:", credsResponse.Credentials);
  return credsResponse.Credentials;
}

// 调用示例
loginAndGetCredentials("test-user", "StrongPassword123!");

2. IAM+STS 示例(Node.js,仅作演示,不推荐生产使用)

依赖安装

npm install @aws-sdk/client-iam @aws-sdk/client-sts

用户注册(创建IAM用户)

const { IAMClient, CreateUserCommand, CreateLoginProfileCommand } = require("@aws-sdk/client-iam");

const iamClient = new IAMClient({ region: "us-east-1" });

async function createUser(username, password) {
  // 创建IAM用户
  const createUserCommand = new CreateUserCommand({ UserName: username });
  await iamClient.send(createUserCommand);

  // 设置登录密码
  const createLoginProfileCommand = new CreateLoginProfileCommand({
    UserName: username,
    Password: password,
    PasswordResetRequired: true // 首次登录需重置密码
  });

  try {
    await iamClient.send(createLoginProfileCommand);
    console.log("IAM用户创建成功:", username);
  } catch (error) {
    // 若用户已存在,清理已创建的用户
    await iamClient.send({ Command: "DeleteUser", UserName: username });
    throw error;
  }
}

// 调用示例
createUser("test-iam-user", "TempPassword123!");

用户登录并获取临时凭证(STS AssumeRole)

const { STSClient, AssumeRoleCommand } = require("@aws-sdk/client-sts");
const { IAMClient, GetUserCommand } = require("@aws-sdk/client-iam");

const stsClient = new STSClient({ region: "us-east-1" });
const iamClient = new IAMClient({ region: "us-east-1" });

// 注意:这里模拟用户提供凭证验证,实际生产中需通过安全方式验证用户密码
async function verifyUserCredentials(username, password) {
  // 实际场景中需通过IAM API验证密码,或使用AWS IAM身份中心,但IAM本身没有直接的密码验证API
  // 此处仅作演示,假设验证通过
  try {
    await iamClient.send(new GetUserCommand({ UserName: username }));
    return true;
  } catch (error) {
    return false;
  }
}

async function assumeRoleForUser(username) {
  const command = new AssumeRoleCommand({
    RoleArn: "arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_USER_ROLE", // 预先创建的用户角色
    RoleSessionName: `${username}-session`,
    DurationSeconds: 3600 // 临时凭证有效期1小时
  });

  const response = await stsClient.send(command);
  console.log("临时凭证:", response.Credentials);
  return response.Credentials;
}

// 调用示例
async function login(username, password) {
  const isValid = await verifyUserCredentials(username, password);
  if (isValid) {
    return await assumeRoleForUser(username);
  } else {
    throw new Error("用户名或密码错误");
  }
}

login("test-iam-user", "TempPassword123!");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:13:17