首页 > 解决方案 > 通过辅助(秘密)ID 检索资源的最佳(RESTful?)方法是什么?

问题描述

我正在开发一个用于帐户邀请的 API,其中一个用户为另一个用户创建了加入平台的邀请,并具有一些特定的权限集。邀请本身将采用众所周知的电子邮件形式,其中包含带有一些随机密钥的链接以接受邀请,类似于我们通常看到的密码重置和帐户确认流程正在实施。

与许多其他 API 一样,此 API 将具有常规的 CRUD 操作,例如 POST /invites/、 GET /invites/{id}、 DELETE/invites/{id}等,基于邀请实体的实际 ID 并实施常规授权方案。但我们还需要一种通过辅助 ID(链接中使用的秘密标识符)检索邀请的方法。

可以考虑只使用秘密作为邀请的主要标识符,但这会产生问题。由于知道秘密意味着允许应用邀请,因此秘密本身不应(总是)被其他 CRUD 调用暴露;对 GET 的响应/invites/通常不包含秘密,这使得在邀请上执行任何其他操作(例如 DELETE)变得有问题。

关于通过多个标识符引用资源的方法已经有几个很好的问题,例如REST API DESIGN - 通过 REST 获取具有不同参数但相同 url 模式和它指向的其他几个资源的资源。通常他们归结为:

人们还普遍指出,从来没有真正需要通过多个唯一标识符来引用实体。但是,如何实现这样的用例呢?

过去我通过使用过滤器模式解决了类似的情况,但由于我一直遇到这种情况,我真的很好奇是否有更好的解决方案。

标签: apiresturiapi-design

解决方案


我最终想出的是定义一个新的集合'authLinks',是'authenticated links'的缩写。“秘密”是此集合中实体的主要标识符。这些实体有一个“资源”字段,它是此 authLink 公开的资源(在本例中为邀请)的链接。当从 API 检索到这样的“authLink”时,服务器将使用它自己的内部凭据检索链接的资源,并将其作为“计算”字段resolvedResource 包含在响应中。

那么,交互将是什么样子:

POST `/authLinks/supserSecretSecret` {"resource": "/invites/someId"} (with appropriate credentials)
> `{"id": "supserSecretSecret", "resource": "/invites/someId", "resolvedResource": {"id": "someId", ...}}`

GET `/authLinks/supserSecretSecret` (without credentials)
> `{"id": "supserSecretSecret", "type": "invite", "resource": "/invites/someId", "resolvedResource": {"id": "someId", ...}}`

系统组件和管理员可以为新的或现有的资源(例如邀请或任何其他类型)CRUD 此类 authLink,并使用适当的创建、更新、删除权限方案。阅读不需要任何权限。

在某些情况下,实现只读机制可能是合适的。尽管我们应该问自己,在这种情况下(否),网络 GET 是否是检索数据的合适方法,但绝对不要忘记设置适当的标头以防止缓存。

对于我的情况,这以一种通用的方式很好地解决了问题,即对于需要通过共享秘密链接访问的任何类型的资源。


推荐阅读