【发布时间】:2014-08-29 17:33:50
【问题描述】:
我正在开发具有非常复杂的访问控制规则的系统中的 API。通常需要复杂的 SQL 查询来确定用户是否具有对特定资源的读取或写入访问权限。这会在我们的客户端应用程序中造成很多复杂性和冗余,因为它们必须了解所有这些规则才能确定是否向用户提供每个对象的 CRUD 选项。
我的目标是减少客户端的大部分复杂性,并在 API 中容纳所有复杂的逻辑。这样,针对我们的 API 编写的新客户端应用程序可以避免在确保 UI 仅向用户提供有效选项时重新实现复杂的访问规则逻辑。
我不确定处理此问题的最佳方法是什么。我正在考虑两种不同的选择,但我不知道是否有更好或更标准的方式向 API 的调用者公开通用访问信息。
选项 1
当调用者对资源实体或它们的集合发出 GET 请求时,每个返回的实体都将返回一个附加的 _allowed_actions 字段,这是一个允许调用者对该实体执行的操作的数组。例如,请求Listing 对象可能会导致以下响应。
GET /listing/5
{
"id": 5,
"address": "123 Foo Street",
"city": "New York",
"state": "New York",
"price": 457000,
"status": "pending",
"_allowed_actions": ["READ", "UPDATE", "DELETE"]
}
仍然不确定如何与客户联系,他们是否有权使用此方法创建资源实体的实例,但也许客户只需要对权限结构保持足够的了解即可自行确定。与创建实例相关的访问规则通常不如 READ/UPDATE/DELETE 访问规则复杂,因此这似乎并不算太糟糕。
选项 2
创建一个元 API,客户端可以向该 API 发出请求,以确定他们可以对每个资源执行哪些操作。例如,检查客户可以对列表做什么:
GET /access-query/listing/5
{
"allowed_actions": ["READ", "UPDATE","DELETE"]
}
并检查列表允许的一般选项,包括 CREATE:
GET /access-query/listing
{
"allowed_actions": ["READ", "CREATE", "UPDATE", "DELETE"]
}
这种方法的好处是,它允许调用者全面了解他们可以以通用方式对每个资源执行什么操作。这样,客户就不必了解创建列表需要“create_listing”权限和非试用用户状态。他们可以简单地提前查询这些信息。
这种方法的缺点是它增加了请求的数量。与其要求客户了解权限逻辑,他们现在必须查询一次以确定他们可以做什么,然后再查询一次。
我对这两种方法都不是特别在意,但目前我能想到的只有它们。有没有更好的方法来解决这个问题?
【问题讨论】:
标签: api rest authorization acl