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

使用Lambda、API Gateway和IAM Policy无法从DynamoDB返回正确值

问题分析与修复方案

核心问题诊断

你的502错误大概率是IAM权限策略配置错误+Lambda代码中ProjectionExpression处理不当共同导致的,具体原因如下:

  • IAM策略中ForAllValues:StringEquals用于单个分区键值的dynamodb:LeadingKeys是错误的,导致所有者身份的请求无法匹配权限规则
  • 当isOwner为true时,设置空字符串的ProjectionExpression会引发DynamoDB请求格式错误
  • 若IDP_REGEX正则无法正确提取Cognito的sub值,会导致isOwner判断错误,触发权限问题

修复步骤

1. 修正IAM权限策略

将Sid1中的ForAllValues:StringEquals改为StringEquals(LeadingKeys是单个值,无需多值匹配前缀):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:xxxxxxx/aws/lambda/test-production:log-stream:*",
            "Effect": "Allow"
        },
        {
            "Sid": "1",
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem"
            ],
            "Resource": "arn:aws:dynamodb:xxxxxxxxxxxxxxxxxxx/xxxxxxx",
            "Condition": {
                "StringEquals": {
                    "dynamodb:LeadingKeys": "${cognito-identity.amazonaws.com:sub}"
                }
            }
        },
        {
            "Sid": "2",
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:BatchGetItem",
                "dynamodb:Query"
            ],
            "Resource": "arn:aws:dynamodb:xxxxxxxxxxxxxxx/xxxxx",
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:Attributes": [
                        "id",
                        "firstName",
                        "lastName"
                    ]
                },
                "StringEqualsIfExists": {
                    "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
                }
            }
        }
    ]
}

2. 修正Lambda代码

  • 移除空字符串的ProjectionExpression,非所有者时才指定属性列表
  • 修正Cognito用户ID提取逻辑,确保正则能正确匹配sub值:
// 标准Cognito sub提取正则
const IDP_REGEX = /CognitoSignIn:(.*)$/;

app.get("/user/:id", async function (req, res) {
    const partitionKey = req.params.id;

    let userId = null;
    const authProvider = req.apiGateway.event.requestContext.identity.cognitoAuthenticationProvider;
    if (authProvider) {
        const matchResult = authProvider.match(IDP_REGEX);
        userId = matchResult ? matchResult[1] : null;
    }

    const isOwner = userId === partitionKey;

    // 仅非所有者时添加属性限制
    const getItemParams = {
        TableName: tableName,
        Key: { id: partitionKey },
        ...(!isOwner && { ProjectionExpression: "id, firstName, lastName" })
    };

    try {
        const data = await ddbDocClient.send(new GetCommand(getItemParams));

        if (!data.Item) {
            res.statusCode = 404;
            return res.json({ error: "Item not found", url: req.url });
        }

        res.json({
            success: "get call succeed!",
            url: req.url,
            data: data.Item
        });
    } catch (error) {
        console.error("GetItem error:", error);
        res.statusCode = error.name === "AccessDeniedException" ? 403 : 500;
        res.json({ 
            error: error.message, 
            errorType: error.name,
            url: req.url 
        });
    }
});

3. 辅助排查动作

  • 查看Lambda的CloudWatch日志,确认具体错误类型(如AccessDeniedException)
  • 验证Cognito用户的sub值与DynamoDB中id字段的一致性(注意大小写、特殊字符)
  • 确认API Gateway已正确配置Cognito授权,requestContext.identity能正常获取cognitoAuthenticationProvider

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:34:55