GraphQL 是近年来广受欢迎的一种 API 设计语言,它让前端开发者能够根据自身需求自由地获取远程数据。但是,不同于传统的 RESTful API,在 GraphQL 中没有明确的 URL 和动词来限制和描述数据操作。这使得前端和后端之间的数据交互更为复杂,同时也引出了一些安全性和访问权限等方面的问题,因此在实际开发中需要进行有效的权限管理。
本文将介绍 GraphQL 中的一些最佳实践,以及如何通过这些实践来加强对远程数据的访问权限管理。
GraphQL 中的权限问题
在 GraphQL 中,所有数据操作都应该通过一个单一的入口(通常是 /graphql
)来进行。这就意味着,如果未对访问者进行权限控制,所有人都可以通过该入口来访问和修改数据。
而要在 GraphQL 中对某个字段或数据类型进行权限控制,需要在后端结构定义(Schema)中对其进行限制。这里需要注意的是,这些限制必须在运行时才能进行判断,因此需要在服务器端进行代码编写和控制。
最佳实践:控制字段和类型的访问权限
最常见的权限管理需求就是限制某个字段或类型的访问权限。在下面的示例中,我们仅允许拥有特定 token 的用户才能查看 profile
字段:
-- -------------------- ---- ------- ----- --------- - - ------ - ------------ ----- -------- - -- ------------------ ----- -- ------------------ --- --------- - ----- --- ----------------- - -- ---------- -------------- ------ - --- -- ----- ------- ------ ------------------ -- - - --
我们在 profile
字段的 resolver 中,首先检查用户是否携带了特定的 token。如果没有,我们将抛出错误以阻止访问。否则,我们可以安全地返回数据。
类似的,我们也可以限制某个类型的访问权限。在下面的示例中,我们禁止未认证的用户访问系统管理员的记录:
-- -------------------- ---- ------- ----- -------- - --- ------------------- ----- ------- ------- - --- - ----- ---------- -- ----- - ----- ------------- -- -------- - ----- --------------- ------------- ----- -------- - -- ---------------- ------- -- -- ------------------ --- -------- -- -------------- - ----- --- ----------------- - ------ ------------- - - - ---
这里我们在 isAdmin
字段的 resolver 中判断了用户是否为系统管理员,如果不是则抛出错误。
最佳实践:控制查询和变更权限
除了限制某个字段或类型的访问权限,我们还可以在 GraphQL 中限制整个查询或变更操作的访问权限。
我们可以通过定义 middleware 函数来控制所有传入的查询或变更操作。这里有一个例子,当用户未登录时,我们将拒绝所有的查询和变更操作:
-- -------------------- ---- ------- -- ----- ---------- -------- ----------------------- ---- ----- - -- ----------- - ------ ----------------------------- - ------- - -- - ---------- ----- ------- --- ----- --- - ---------- ------------------- ------------------- ------------- ------- -------- ----
这里,我们定义了 isAuthedMiddleware
来判断用户是否已登录。如果未登录,则返回 401 状态码。
之后,我们将 isAuthedMiddleware
作为 middleware 函数,通过 app.use()
注入到 GraphQL 服务中。这样,所有经过 /graphql
接口的请求都必须先经过这个 middleware,如果未通过则直接拒绝。
最佳实践:控制查询结果细节
在 GraphQL 中,前端可以精确地控制返回结果的细节。但这也可能引入一些安全性问题,比如:某个查询应该返回什么级别的数据、是否显示敏感数据等。在这些情况下,我们可以通过 HOC(高阶组件)来控制返回值的细节:
-- -------------------- ---- ------- -- -- --- -------- -------- ------------------------------ - ----- ---------- - ------- -- - ----- - ----------- - - ------ ----- -------- - - --------- ------ - ------- -------------- - -- ------ ------------------ -- ------ ----------- - -- -- --- ------- -------- ----- --------- - - ------ - -------- --------------------------- ----- -------- -- - ------ ---------------------------- --- -- -------- -- --------- - ----------- --------------------------- ----- -------- -- - ----- - --- ----- - - ----- ------ ------------------ ------- --- -- -------- - --
这里我们定义了一个 withLimitToOwnRecords
的 HOC,它将包装我们的 resolver 并通过 currentUser
测试数据,把其与指定记录或类型对象并检查是否属于该用户,如果不属于则抛出错误以阻止访问。
结论
在 GraphQL 中,为了加强对远程数据的访问权限管理,需要对字段和类型的访问权限、查询和变更权限以及查询结果细节等方面进行限制。
本文介绍了一些最佳实践,如限制字段和类型的访问权限、控制查询和变更权限以及通过 HOC 动态控制返回值。通过掌握这些最佳实践,前端开发者可以更加安全地访问并使用远程数据。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67166cc1ad1e889fe21c7adc