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

如何在AWS环境下实现React网站获取用户数据?

React + AWS Cognito + RDS 实现登录后获取个人数据方案

你的核心思路方向正确,仅数据库表设计需要调整,先明确完整可行的流程:

  1. 用户通过Cognito登录后,回调URL会携带授权码或直接返回JWT令牌
  2. 前端获取并存储令牌,解码得到用户的唯一标识(推荐用Cognito分配的sub字段,比邮箱更稳定)
  3. 前端携带令牌调用已配置的API Gateway,触发关联的Lambda函数
  4. Lambda验证令牌合法性后,连接RDS查询该用户对应的数据,返回给前端渲染表格

疑问解答

1. JWT令牌的获取与API调用

获取JWT令牌

  • 若使用Cognito Hosted UI,回调URL会收到code参数,前端需用该code向Cognito令牌端点(https://你的Cognito域名/oauth2/token)发起POST请求,换取Access Token和ID Token(优先用Access Token调用API)
  • 拿到令牌后,存在sessionStorage(短期会话更安全,避免XSS长期泄露)或localStorage中

API调用携带令牌

每次调用API Gateway都必须携带令牌,放在请求头的Authorization字段,格式为Bearer <Access Token>。React中示例代码:

const fetchUserData = async () => {
  const token = sessionStorage.getItem('accessToken');
  const res = await fetch('你的API Gateway访问URL', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });
  const userData = await res.json();
  // 渲染表格逻辑
};

API Gateway的Cognito授权会自动验证令牌有效性,验证通过才会触发Lambda。

2. 数据库实例设计

绝对不要给每个用户单独建表,这是数据库设计的反模式,会导致维护成本剧增。正确设计:

  • 创建一张统一的用户业务数据表,比如user_biz_data
  • 核心字段包含:
    • id(自增主键)
    • user_sub(Cognito用户的永久唯一标识sub,非空,建立索引)
    • email(可选,作为冗余字段)
    • 其他业务相关字段(如nickname, record_date, content等)
  • 查询时用user_sub作为条件,比邮箱更可靠(用户可能修改邮箱,但sub不会变更)

3. 使用AWS Amplify vs 不使用的实现方案

方案一:使用AWS Amplify(简化开发)

Amplify已封装Cognito、API Gateway的集成逻辑,大幅减少代码量:

  1. 关联现有AWS资源:
amplify init
amplify add auth # 选择关联已有的Cognito用户池
amplify add api # 选择关联已有的API Gateway
amplify push
  1. React端核心代码:
import { Auth, API } from 'aws-amplify';

// 跳转Cognito Hosted UI登录
const handleSignIn = async () => {
  await Auth.federatedSignIn();
};

// 获取用户数据
const getUserData = async () => {
  const user = await Auth.currentAuthenticatedUser();
  const token = user.signInUserSession.accessToken.jwtToken;
  const data = await API.get('你的API名称', '/数据接口路径', {
    headers: { Authorization: `Bearer ${token}` }
  });
  // 渲染表格
};
  1. Lambda连接RDS代码:
const mysql = require('mysql2/promise');

exports.handler = async (event) => {
  // API Gateway授权后,用户sub会自动存放在该字段
  const userSub = event.requestContext.authorizer.claims.sub;
  
  // 建立RDS连接(建议用Secrets Manager存储数据库凭证,避免硬编码)
  const conn = await mysql.createConnection({
    host: '你的RDS端点',
    user: '数据库用户名',
    password: '数据库密码',
    database: '目标数据库名'
  });
  
  // 查询用户数据
  const [rows] = await conn.execute('SELECT * FROM user_biz_data WHERE user_sub = ?', [userSub]);
  await conn.end();
  
  return {
    statusCode: 200,
    body: JSON.stringify(rows)
  };
};

方案二:不使用AWS Amplify(手动实现)

  1. 前端处理登录与令牌获取:
// 回调页面处理授权码换令牌
const handleCallback = async () => {
  const code = new URLSearchParams(window.location.search).get('code');
  const tokenRes = await fetch('https://你的Cognito域名/oauth2/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: '你的Cognito应用客户端ID',
      code,
      redirect_uri: '你的回调URL'
    })
  });
  const tokens = await tokenRes.json();
  sessionStorage.setItem('accessToken', tokens.access_token);
  // 重定向到应用页
  window.location.href = '/app';
};

// 应用页调用API
const fetchUserData = async () => {
  const token = sessionStorage.getItem('accessToken');
  const res = await fetch('你的API Gateway访问URL', {
    method: 'GET',
    headers: { 'Authorization': `Bearer ${token}` }
  });
  const userData = await res.json();
  // 渲染表格逻辑
};
  1. Lambda连接RDS的代码与方案一完全一致,API Gateway已完成令牌验证,Lambda可直接读取event.requestContext.authorizer.claims.sub获取用户标识

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:01:00