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

React Native+Amplify:如何限制CognitoUser仅操作自身DynamoDB数据?

问题背景

我在React Native项目中使用Amplify与Cognito,数据存储于DynamoDB,需要实现用户仅能对自身数据执行CRUD操作。查阅资料得知需将identityID作为DynamoDB表项的主键/哈希键,已按此实现相关代码:

前端创建数据的代码:

import { API, Auth } from "aws-amplify";

const createItemDB = async () => {
  API.post("nutritionAPI", "/items", {
    body: {
      userID: `${(await Auth.currentUserCredentials()).identityId}`,
      dateID: "february23",
    },
    headers: {
      Authorization: `Bearer ${(await Auth.currentSession())
        .getIdToken()
        .getJwtToken()}`,
    },
  })
    .then((result) => {
      // console.log(result)
    })
    .catch((err) => {
      console.log(err);
    });
};

Amplify生成的后端Lambda处理代码(路径:amplify/backend/function/src/app.js):

app.post(path, function(req, res) {
  if (userIdPresent) {
    req.body['userId'] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH;
  }
  let putItemParams = {
    TableName: tableName,
    Item: req.body
  }
  dynamodb.put(putItemParams, (err, data) => {
    if (err) {
      res.statusCode = 500;
      res.json({error: err, url: req.url, body: req.body});
    } else {
      res.json({success: 'post call succeed!', url: req.url, data: data})
    }
  });
});

我已按照教程创建了Federated Identities Pool并关联用户池,但不清楚其具体作用,希望得到相关帮助。


解答

一、Federated Identities Pool(联合身份池)的核心作用

  • 统一身份标识:不管用户是通过Cognito用户池登录、第三方社交账号登录,还是匿名访问,身份池都会为每个用户分配一个唯一且固定的identityId——这就是你用来作为DynamoDB主键的ID,是跨登录方式的统一用户标识。
  • 权限映射:身份池会将用户身份(如Cognito认证用户、匿名用户)映射到对应的IAM角色,比如认证用户对应authRole,匿名用户对应unauthRole,这些角色直接控制用户能访问哪些AWS资源(比如你的DynamoDB表)。
  • 简化权限批量管理:无需给每个用户单独配置IAM权限,只需通过身份池的角色批量设置规则。比如给authRole配置“仅能访问userId等于自身identityId的DynamoDB条目”,这是实现“用户仅能操作自身数据”的核心底层逻辑。

二、当前代码的优化与加固建议

前端代码优化

你当前手动传入userID的操作可以省略——后端代码里的userIdPresent逻辑会自动从请求上下文获取cognitoIdentityId并赋值给userId,比前端传入更安全(避免前端数据被篡改)。优化后代码:

import { API, Auth } from "aws-amplify";

const createItemDB = async () => {
  try {
    const token = (await Auth.currentSession()).getIdToken().getJwtToken();
    const result = await API.post("nutritionAPI", "/items", {
      body: {
        dateID: "february23",
      },
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });
    // 处理返回结果
  } catch (err) {
    console.log(err);
  }
};

改用async/await替代then/catch,代码可读性更强。

后端权限加固

要彻底实现用户隔离,必须给DynamoDB配置细粒度IAM权限,配合身份池的authRole使用。示例IAM策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": "arn:aws:dynamodb:你的AWS区域:你的账号ID:table/你的表名",
      "Condition": {
        "ForAllValues:StringEquals": {
          "dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
        }
      }
    }
  ]
}

该策略强制要求用户仅能访问主键(LeadingKeys)等于自身identityId的条目,从底层权限层面杜绝越权访问。

后端代码注意点

代码中的userIdPresent是Amplify创建API时根据你的配置自动生成的:如果创建时勾选了“添加认证”并关联Cognito,这个变量会为true,后端会自动写入identityId到userId字段,无需前端干预。

三、整体流程梳理

  1. 用户通过Cognito用户池登录,Amplify自动获取用户身份凭证;
  2. 前端调用API时携带JWT Token,API Gateway验证Token后将用户identityId写入请求上下文;
  3. 后端Lambda从请求上下文取出identityId,写入DynamoDB条目的userId字段;
  4. IAM策略根据用户identityId,限制其仅能访问自身的DynamoDB数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:40:30