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