【问题标题】:Resource ownership in REST APIREST API 中的资源所有权
【发布时间】:2017-06-08 12:00:45
【问题描述】:

在以下场景中:

  • 用户可以创建游戏
  • 创建游戏的用户称为所有者
  • 游戏在全球范围内拥有自己的唯一 ID。
  • 其他用户可以加入他们不拥有的游戏,这些被称为玩家

可以向/game/{id} 发送请求以获取游戏数据,每个客户端的数据都应该相同,例如:

{
   name: 'My Game',
   sport: 'Football'
   ...
}

假设我们必须在主游戏屏幕中为游戏所有者显示“设置”链接。普通玩家无法显示此“设置”链接。

玩家和所有者都可以看到主游戏屏幕。

如何验证此资源的所有权以向用户显示不同的组件?

  • 我认为在响应中添加ownerId 是一种责任,因为可能会更改客户端的值,对吗?
  • 此外,添加 isOwner 字段将无法缓存响应。

【问题讨论】:

    标签: rest api restful-architecture restful-url


    【解决方案1】:

    这里的答案可能在于 HATEOAS 类型的结构。您的资源应包含指向其他信息/子项/列表等的可导航链接列表。如果“设置”是请求用户的选项,则应将指向设置的链接作为对象的一部分返回,否则没有此类链接会存在。

    缓存:这确实存在问题,但可以解决。

    【讨论】:

    • 在这种情况下,从缓存的角度来看,这将如何解决?通过这种方法,响应变得基于用户。
    • 上述问题并不是真正可缓存的——您会根据用户获得不同的输出,这就是我们通常不缓存数据的原因。您必须将其拆分为两个请求,一个用于对象,另一个用于其元数据(包括对设置的引用)。初始的 dto 可以缓存,但用户特定的数据不能。
    【解决方案2】:

    让我们来谈谈服务器应用程序和客户端应用程序。客户端应用程序包含游戏主屏幕,并且应该根据某事显示或隐藏一些窗格。

    服务器应用程序应该提供这个东西。由于服务器应用程序是 REST,它应该提供一些资源。资源是什么类型的,应该放在哪里?

    GET /games/{gameId}/users/{userId}/something
    GET /users/{userId}/games/{gameId}/something
    

    可以将此某事称为用户的权利或许可。这是单独的资源吗?可能不。这样就可以实现方法了

    GET /games/{gameId}/users/{userId}
    

    该方法将返回用户的个人资料和ID为{gameId}的游戏的相应权限,如下所示:

    {
        givenNames: 'Miguel de Cervantes',
        familyName: 'Saavedra',
        totalScore: 10342,
    
        permissions: {
            canClose: false,
            canSetup: false,
            . . .
        }
    }
    

    当然,服务器应用程序应该检查每个客户端请求的权限。

    【讨论】:

    • 谢谢,这是我第一次看到这种方法,所以我对在应用程序中遵循这种类型的权限处理的含义有几个问题:当前用户的个人资料数据可以是通过请求/users/{id} 端点获取。是否可以在这个建议的端点 (/games/{gameId}/users/{userId}) 中也包含与用户相关的数据?
    • 在这种情况下,这意味着必须再进行一次请求才能获得用户的许可,这不会降低应用程序的性能吗?由于permissions 节点将成为整个应用程序的标准,那么在文档中记录不同类型权限键(canClosecanSetup...)的最佳方式是什么?
    • 关于第一个问题。是的,会没事的。有时子资源可以通过不同的路径访问,尤其是当存在多对多关系时。你有游戏,你有用户,你有指定用户的所有游戏。
    • 关于第二个问题。一般规则是一次传递尽可能多的数据(模式Remote Façade)。 Permissions 是一个简单的非大型集合,因此您可以将其包含在用户对象中。在JSON API 中,您可以使用include 查询参数来传递所需的可选字段。
    【解决方案3】:

    我认为首先你必须解决与资源责任相关的概念问题,因为返回游戏信息的资源不应该返回诸如“看到或不看到按钮”之类的安全信息。

    所以,我会创建一个特定的资源来返回这样的安全信息。 在这个特定的安全资源中,对于上面提到的情况,我不会通过 URL 传递任何参数,而是通过身份验证哈希获取用户 ID 来验证他是否是游戏所有者,返回一个简单的响应,比如 true 或 false 来知道如果该用户可以看到该按钮。

    显然,该资源可以回答很多关于其他屏幕和按钮的安全信息。

    类似的资源:

    GET /security/buttons/{buttonId}
    

    未来:

    GET /security/screens/{screenId}
    GET /security/functionalities/{functionalityId}
    GET /security/actions/{actionId}
    .
    .
    .
    

    【讨论】:

    • 按钮只是一个抽象的例子,因为我不能在这里分享实际场景。该按钮代表“与游戏所有者专有相关的信息和操作。至于您的回答,这不违反Resource conceptRFC 3986吗?
    猜你喜欢
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多