我正在开发一个简单的应用程序(ios),每个用户都可以向其他用户(他们的Facebook好友)发送简单的消息(每个消息都由几个数据槽组成,暂时都是字符串)。人们通过Cognito使用他们的Facebook帐户登录,我使用DynamoDB中的一个表管理用户帐户,其中主键是Facebook id(辅键是唯一的消息id)。当用户A向用户B发送消息时,两个几乎相同的行被添加到表中,它们包含消息,它们之间唯一的区别是主键(一个是A的facebook id,另一个是B的)。因此,当用户登录并检查他的帐户时,她会检索与她的脸书id对应的所有行,从而访问她发送的消息和已经发送给她的消息。
目前,每个用户都可以访问表中的所有行,这是一个安全缺陷。我查看了一些文档,在这种情况下,似乎可以通过向IAM策略添加以下片段来执行细粒度访问控制:
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${graph.facebook.com:id}"
]
}
}
不幸的是,${graph.facebook.com:id}
不适用于Cognito,我应该使用${cognito-identity.amazonaws.com:sub}
来识别用户。问题是,使用后者需要使用Cognito id作为主键,而不是Facebook id,这导致了我的问题:可以获得朋友的Facebook id,但不能获得他们的Cognito id,这使得无法使用以前的架构向他们发送消息。
在保留Cognito的同时,有什么可能的解决方案吗?或者我应该在没有它的情况下对用户进行身份验证吗?此外,欢迎对我的应用程序设计发表任何评论和批评。
如果您需要使用用户的facebookid,请使用Web Identity Federation。文档有点过时,但aws-mobile和js-sdks提供了一个web身份证书提供商。
如果您允许对所有密钥进行写访问,而只允许对与凭据相关的facebook id进行读访问,则这种方法应该有效。
如果仅使用Cognito Identity池,则可以使用默认的Identity提供程序映射。对于Facebook来说:
sub
->映射到user_id
,例如112177216992379
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${graph.facebook.com:sub}"
]
}
}