GraphQL 中如何处理无权限请求?

阅读时长 7 分钟读完

在 GraphQL 应用程序开发过程中,我们经常会遇到需要对请求进行权限控制的情况。比如,某些查询或者修改操作需要特定的用户权限才能进行,而其他用户则不能执行。在这些场景下,我们需要能够识别用户的身份,并在必要时阻止他们发起无权限请求。本文将介绍在 GraphQL 中如何识别用户身份、控制权限,以及如何处理无权限请求。

识别用户身份

在 GraphQL 应用程序中,我们可以通过某些方式来识别用户身份,例如:

  • 通过 HTTP 请求头中的认证令牌(例如 Authorization 头)来进行认证。
  • 在每个 GraphQL 查询的参数中加入用户 ID(例如 userID 参数)。

这里以 HTTP 请求头方式来说明。当客户端发送 GraphQL 请求时,我们需要从请求头中获取认证令牌,并将其加入到 GraphQL 上下文中,以便后续的解析器和查询处理器能够使用它。示例代码如下所示:

-- -------------------- ---- -------
----- - ------------ - - -------------------------
----- - --------------- - - ------------------------------
----- - --------- - - -------------------

----- -------- - -
  ---- ----- -
    ----- ----
  -

  ---- ---- -
    --- ---
    ------ -------
  -
--

----- --------- - -
  ------ -
    ----- -------- ----- -------- -- -
      ----- ------ - ---------------
      -- ---- -- ------------
    --
  --
--

----- ------ - --- --------------
  ---------
  ----------
  -------- -- --- -- -- --
    ------- ---------------
  ---
---

----------------------- --- -- -- -
  ------------------- ----- -- ---------
---

在示例代码中,getUserId 函数可以根据请求头中的认证令牌获取用户 ID。如果无法识别用户身份,则认为没有权限请求。

控制权限

在识别了用户身份之后,我们需要对用户请求的操作进行权限控制。在 GraphQL 中,我们可以定义字段级别或者类型级别的权限控制。在这里,我们以字段级别的权限控制为例。

假设我们只有管理员才能够查询用户的具体信息(例如电子邮件地址)。我们可以在查询的类型定义中将 email 字段定义为只有管理员可以访问:

-- -------------------- ---- -------
----- - ------------- --- - - -------------------------
----- - --------------- - - ------------------------------
----- - --------- - - -------------------

----- -------- - ----
  ---- ----- -
    ----- ----
  -

  ---- ---- -
    --- ---
    ------ ------- ------------ --------
  -
--

----- --------- - -
  ------ -
    ----- -------- ----- -------- -- -
      ----- ------ - ---------------
      -- ---- -- ------------
    --
  --
  ----- -
    ------ -------- ----- -------- -- -
      ----- ----- - --------------
      -- -------------------------- -
        ----- --- ---------- -------------
      -
      ------ -------------
    --
  --
--

----- ----------- - -
  ----- -
    ------ -- ----- ------- -- -- -
      ----- ----- - --------------
      -- -------------------------- -
        ----- --- ---------- -------------
      -
    --
  --
--

----- ------ - --- --------------
  ---------
  ----------
  -------- -- --- -- -- -
    ----- ------ - ---------------
    ----- ---- - --------------------
    ------ -
      ------- --------
      ------ -----------
    --
  --
---

----------------------- --- -- -- -
  ------------------- ----- -- ---------
---

在示例代码中,我们定义了一个 @auth 指令,只有指定的角色才能访问该字段。在每个查询解析器中,我们根据用户的角色信息进行访问控制,如果用户没有相应的角色,则抛出错误,拒绝请求。

同时,我们还可以定义类型级别的权限控制,以对某个类型下的所有字段进行统一限制。这里不再赘述,有兴趣的读者可以参考 GraphQL 官方文档。

处理无权限请求

当用户发起无权限请求时,我们需要对这些请求进行合适的处理。常见的处理方式包括:

  • 抛出错误:在每个解析器中抛出错误,返回错误信息给客户端。
  • 隐藏字段:在查询结果中屏蔽掉无权限访问的字段,只返回有权访问的字段。
  • 改变响应:例如在查询结果中做一些替换或者空值处理。

其中,抛出错误是最常见的处理方式,也是最保险的方式。我们可以在每个解析器中进行验证,抛出相应的错误信息给客户端。示例代码如下所示:

-- -------------------- ---- -------
----- --------- - -
  ------ -
    ----- -------- ----- -------- -- -
      ----- ------ - ---------------
      ----- ----- - --------------
      ----- ---- - ---------------------
      -- -------- --- ------ -- ------------------------- -
        ----- --- ---------- -------------
      -
      ------ -----
    --
  --
--

在示例代码中,如果查询的用户 ID 不是当前用户 ID,并且当前用户也不是管理员,则抛出 Not authorized 错误,拒绝请求。客户端可以根据错误信息做相应的处理,例如提示用户重新登录,或者提醒用户其没有相应的权限。

结论

在 GraphQL 应用程序中,我们需要对用户身份进行验证,并进行权限控制。通过字段级别或者类型级别的授权定义,我们可以限制用户访问某些特定字段或者类型。当用户发起无权限请求时,我们可以选择抛出错误、隐藏字段或者改变响应等合适的处理方式。控制好用户访问权限,可以保证应用程序的安全性和稳定性。

参考

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67213b922e7021665e06c534

纠错
反馈