SPA应用中基于Cognito与DynamoDB的用户数据安全访问验证问询
你的核心需求是确保用户只能访问自己的DynamoDB数据,防止恶意使用他人userId越权查询,用Cognito的OAuth令牌完全可以实现,而且是这套架构的标准做法,具体实现步骤如下:
1. 用API Gateway(或Lambda URL)做身份拦截
把数据API部署在API Gateway后面,配置Cognito用户池作为授权方。所有请求必须携带Cognito签发的有效ID Token或Access Token,无效令牌会直接被API Gateway拦截,连后端Lambda都到不了。
请求通过授权后,API Gateway会自动解析令牌中的用户信息(比如唯一标识sub)并放到请求上下文里,后端Lambda可以直接读取,不用自己手动解析令牌。
2. 从令牌提取用户ID,禁止前端传入参数
这是杜绝越权的关键:绝对不要让前端在请求参数、Body或URL里传递userId。所有数据操作(查询、存储、更新)的userId,都从令牌解析出的sub字段获取(这个sub就是Cognito用户的唯一标识,和你DynamoDB里的userId完全对应)。
举个Node.js Lambda的实现示例:
const AWS = require('aws-sdk'); const dynamodb = new AWS.DynamoDB.DocumentClient(); exports.handler = async (event) => { // 从授权上下文获取当前用户的sub(即userId) const userId = event.requestContext.authorizer.claims.sub; // 查询当前用户的数据,完全不依赖前端传入的参数 const params = { TableName: 'YourUserTable', Key: { userId: userId } }; const result = await dynamodb.get(params).promise(); return { statusCode: 200, body: JSON.stringify(result.Item) }; };
这样前端就算想传入别人的userId,Lambda也会直接忽略,只处理当前令牌所属用户的数据,从根源上阻断越权可能。
3. 给Lambda配置DynamoDB细粒度权限(双重保障)
为了进一步提升安全性,给Lambda的IAM角色添加DynamoDB权限时,加上条件限制:只允许Lambda访问userId等于当前用户sub的数据。
IAM权限配置示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem" ], "Resource": "arn:aws:dynamodb:region:account-id:table/YourUserTable", "Condition": { "ForAllValues:StringEquals": { "dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"] } } } ] }
就算Lambda逻辑出现漏洞(比如不小心误用了前端传入的参数),IAM也会直接阻止这次访问,形成双重防护。
补充:OAuth令牌的选择建议
- ID Token:适合SPA向API传递用户身份信息,令牌内置用户基础信息(sub、email等),API Gateway可以直接验证签名和有效期,上手简单。
- Access Token:更适合服务间调用场景,但对于SPA的身份验证需求,ID Token完全够用。
这套方案既通过OAuth令牌完成了请求者身份验证,又彻底规避了用户通过篡改userId越权访问他人数据的风险,完全匹配你的核心需求。
内容的提问来源于stack exchange,提问作者Armen Babakanian

