3.9.8. 集合属性的安全约束
考虑下面这个情况:
数据模型包含
Order
和OrderLine
实体,形成了一对多的关系。REST 客户端获取了一个
Order
实例,并且带着嵌套的OrderLine
实例集合。有些安全约束可以过滤掉某些
OrderLine
实例,从而使得客户端不加载这些实例,也不知道这些实例的存在。比方说,line5
不会被加载,但是存在于数据库。如果客户端从集合中删除了一条,比如说
line2
,然后将整个组合通过/entities/{entityName}/{entityId}
API 端点进行保存,会有两种可能的输出:
如果这个约束从实体被加载之后没有更改过,框架会首先在
OrderLine
集合里面恢复被过滤的line5
实例然后只删除line2
,这个是正确的行为。但是如果这个约束在什么时候更改了,导致
line5
能被用户看见,此时,框架就不会正确的在集合内恢复这些被过滤的实例(因为从目前的约束状态看,line5
应该被客户加载过)。结果导致line2
和line5
都会被删除。
如果对上面描述的场景有担忧,可以通过这种方式排除数据丢失的隐患:在表示实体的 JSON 中发送一个特殊的系统属性。这个属性被称为 __securityToken
并且会自动包含在返回的 JSON 中,如果 cuba.rest.requiresSecurityToken 设置成 true
的话。REST 客户端的责任就是在保存实体的时候将这个属性带入并返回。
实体 JSON 包含安全令牌的示例:
{
"id": "fa430b56-ceb2-150f-6a85-12c691908bd1",
"number": "OR-000001",
"items": [
{
"id": "82e6e6d2-be97-c81c-c58d-5e2760ae095a",
"description": "Item 1"
},
{
"id": "988a8cb5-d61a-e493-c401-f717dd9a2d66",
"description": "Item 2"
}
],
"__securityToken": "0NXc6bQh+vZuXE4Fsk4mJX4QnhS3lOBfxzUniltchpxPfi1rZ5htEmekfV60sbEuWUykbDoY+rCxdhzORaYQNQ=="
}
__securityToken
属性包含了被过滤的实例标识符的加密串,从而使得框架总是能恢复需要的信息而不管约束怎么改变。