GraphQL 是一种新兴的数据查询语言,越来越多的公司开始使用 GraphQL。在很多场景下,需要对不同的用户或者角色,对于数据的查询或者修改进行权限控制。本文将详细介绍如何在 GraphQL 中实现数据的权限控制。
为什么需要在 GraphQL 中实现数据的权限控制?
在开发 web 应用程序时,我们经常要面临以下场景:
- 必须限制用户的权限,以确保他们只能访问其拥有的资源。
- 需要保护资源以确保不受未授权的访问。
- 用户应只能执行与其角色或权限匹配的操作。
GraphQL 能够良好的解决以上问题,但本身它并不提供权限控制,需要我们自行实现。
如何在 GraphQL 中实现数据权限控制?
- 确定数据层次
通过定义类型,GraphQL 构建了关系团结的层次结构。你需要对业务数据建模,并理清业务数据之间的关系。
- 鉴别用户权限
在每一个 resolver 中,都可以获取当前请求的用户信息。通过获取用户信息,即可鉴别用户是否拥有操作数据的权限。
例如,通过 JWT token 获取用户信息,其中包含用户角色等信息。
-- -------------------- ---- ------- ----- ------- - ----- -- - ----- ----- - -------------------------- -- ------- - --- - ------ ----------------- ------------------------ - ----- ----- - ----- --- ------------------------- ------- --- -------- ------ ----- --------- - - --
- 分配角色和权限
通过 GraphQL 的 schema 指令 可以方便的分配角色和权限。
例如,我们希望只有管理员才能变更文章信息。
type Mutation { updateArticle(id: ID!, input: ArticleInput) @hasRole(role: "ADMIN") @validateInput(inputType: "ArticleInput") : Article }
定义 hasRole 和 validateInput 两个指令。
-- -------------------- ---- ------- -- ------- ----- ----- ---------------- - - -------- ----- ------- ---------------------- - --------------------------- ---- - ----- ------------ - --------------- ----- ---- - -------------- ------------- - -------- ----- -------- ----- -- - ----- - ---- - - ------------- -- ----- --- ------------- - ----- --- ---------- ---- ---- --------------- ---------- -- ---------- - ------ ------------ ----- -------- ------ -- - -- -- ------------- ----- -------------- ----- ------- ---------------------- - -------------------------------- ---- - ----- ----------------- - -------------------- ----- ---- - -------------- ------------- - -------- ----- -------- ----- -- - ----- - ---- - - ----------- -- ---------------- --- ------------------ - ----- --- -------------- ----- ----- -------- ----------------------- - ------ ------------ ----- -------- ------ -- - - --
通过自定义指令,即可完成代码中的权限控制。validateInput 的指令主要用于对输入数据进行校验。
- 过滤查询结果
在某些情况下,管理员可能需要查看所有用户的信息,但普通用户只能查看自己的信息。这时,我们需要在 resolver 中对结果进行控制。
async allUser(parent: any, args: any, context: any, info: any) { const currentUser = context.user; if (currentRole !== 'ADMIN') { // 如果当前角色不是管理员,则查询当前用户的信息 return await User.find({ _id: currentUser.id }); } return await User.find(); // 如果当前角色是管理员,则返回所有用户的信息。 }
总结
在 GraphQL 中,由于其强大的类型系统和 schema 指令,我们可以非常方便的在 GraphQL 中实现数据权限控制。本文介绍了如何通过自定义指令,在 resolver 中进行权限控制,以及如何过滤查询结果。
GraphQL 的权限控制需要在后端开发中实现,这也是其与 RESTful API 不同的一点。每个 resolver 都需要经过鉴权,虽然会稍稍增加一点工作量,但是在保护用户隐私和保护系统安全方面是至关重要的。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649be2ec48841e98948a537d