我正在寻找一些最佳实践,一般是对机密分层数据进行建模,特别是使用DynamoDB。
最好用一个例子来解释这个场景:
假设我们有一些users
。每个user
都有products
个。每个product
都包含多个parts
。
典型用例:
products
user
parts
product
到目前为止,我已经在DynamoDB中对此进行了这样的建模:
Users
----------------
HashKey: UserId
Products
-------------------
HashKey: UserId
RangeKey: ProductId
Parts
-------------------
HashKey: ProductId
RangeKey: PartId
数据是保密的,可通过经过身份验证的REST端点访问,其中身份验证令牌可以映射到UserId
。允许每个用户 通过某些组概念查看其他用户的数据。
列出给定用户的所有产品很简单,因为UserId
是产品表中的关键字:
GET /users/111/products
变为简单的Query(Table=Products, UserId=111)
但请考虑列出给定产品的所有部分的情况:
GET /users/111/products/222/parts
如果我只是做一个Query(Table=Parts, ProductId=222)
,那么我将快速获得所需的数据,但我不会保护其他用户查询属于用户111的数据,只要他们知道ProductId
222(实际上,ID:s当然是UUID:s或类似的,所以不容易猜到):
GET /users/119/products/222/parts
...将导致恶意用户119检索不属于他的数据,前提是没有做任何事情来解决这个问题。 所以在这里我想我需要做一些像这样的事情:
UserId
并将其包含在查询条件中(这基本上意味着它在扫描时将匹配所有行或无行通过ProductId
标识的集合:Query(Table=Parts, ProductId=222, UserId=111)
UserId_ProductId
表Parts
(“111_222”)等复合HashKey
醇>
如果我需要返回401而不是空数据,则选项1似乎是唯一的方法。但是,如果我们想象一个更深层次的数据,例如“具有带有附件的部分的消息的收件箱的用户”似乎这种方法最终可能很昂贵(列出部分P的所有附件可能导致查询以检查部分P属于消息M,消息M属于收件箱I和那个收件箱我属于用户U,依此类推。)
对于哪种方法最有利,有没有人有任何好的论据?或者我做了一些愚蠢的事情,应该完全以其他方式对我的数据进行建模?