如何在 GraphQL 中安全地处理用户输入

随着前端技术的快速发展,越来越多的应用程序采用了 GraphQL 作为后端数据查询和交互的标准。GraphQL 旨在提供一种更高效、更灵活和更安全的数据查询机制。然而,在 GraphQL 中处理用户输入时,保障安全性仍然是一项重要的任务。

在本文中,我们将学习如何在 GraphQL 中安全地处理用户输入,探究此过程的深度和学习成果,并提供相关的指导意义和示例代码。

为什么安全性在 GraphQL 中如此重要?

任何应用程序中,安全性总是排在最优先的位置。使用 GraphQL 的应用程序也不例外。在 GraphQL 中,安全性特别重要,因为 GraphQL 的数据查询过程更加灵活,查询语句可以由客户端组成,其中包括对所有字段的查询、过滤以及排序。因此,GraphQL 在其语言本身中并没有像 RESTful API 那样实施 OAuth2、ClientCredentials 等身份验证和授权机制。如果不注意安全性问题,那么这些查询可能会被恶意的攻击者利用来获取一些敏感信息,或者进行一些恶意行为。

因此,实现安全的 GraphQL 函数是至关重要的。我们如何在 GraphQL 中实现安全的数据查询和输入处理呢?下面是一些我们可以采取的技术策略:

采取的策略:

  1. 使用静态分析工具- 开发人员使用像 ESLint 和 TSLint 这样的静态代码分析工具,以确保 GraphQL 查询中的验证和过滤器是正确的, 业务逻辑是一致的,能更好的保证 GraphQL 编排的正确性和数据查询的安全性。
  2. 启用安全 GraphQL 处理器- 当应用程序在生产环境中部署时,应该始终启用安全的 GraphQL 处理器,如graphql-shield,它会执行一些运行时的检查和过滤操作。它能在查询即将执行之前验证用户身份,显式地指定哪些查询字段是安全的,并能防止一些服务器端的技术攻击行为,如 DDoS 攻击和访问限制等。
  3. 对 GraphQL 查询进行身份验证和授权- 开发人员应该为所有 GraphQL API 的查询和突变设置身份验证和授权策略,以防止未授权的用户进行读写突变操作。GraphQL API 通常使用 jwt token 来实现身份验证,但也需要考虑 csrf 攻击和 DOS 攻击。

下面,我们来看看如何在 GraphQL 中安全地处理用户输入:

在 GraphQL 中安全地处理用户输入

一些开发人员在编写 GraphQL 代码时,可能会犯一些严重的安全错误,例如在客户端将查询字符串传递给服务器,或在数据库查询、更新或删除操作中使用未经验证的客户端输入。这些错误可能会导致服务器实现中的重大安全漏洞,使客户端的敏感信息遭到泄露,甚至使整个服务器暴露于攻击者的攻击之下。

为了避免这种情况,在 GraphQL 中,我们建议使用参数型式的查询,并使用对参数进行适当检验的安全数据访问模式。以下是在 GraphQL 中实现安全输入处理的步骤:

1. 使用参数查询签名来定义 GraphQL 文件

为了在 GraphQL 中安全处理输入,最简单的方法是使用 GraphQL 查询语言中的名称参数签名来定义 GraphQL 查询。以下是一个查询用户信息的示例:

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

在这个查询中,我们定义了名称为$id的字符串参数。接下来,我们需要通过传递这个参数来执行查询。

2. 在输入处理中尽可能地验证和过滤参数

在 GraphQL 中处理用户输入的重要方法是在输入处理中使用参数验证和过滤器机制。GraphQL 使用了一个名为 GraphQL 类型系统(GraphQL Type System)的强大系统,具有它自己的架构和规则。我们应该使用这个类别系统来定义 GraphQL 查询参数的类型,并使用它来检查 GraphQL 客户端的请求。

在 GraphQL 的类别系统中,有一些类型是内置的,例如 String、Int、Boolean 等。这些内置类型不能够满足完全灵活的需求。因此,我们可以通过创建自定义类型,来进行更灵活的输入验证和过滤。例如在以下示例中,我们可以使用 GraphQL 类型系统定义一个自定义类型 user,在类型中定义查询所需的每个字段,并在客户端-服务器端之间使用此类型来传递参数。

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

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

在进行 GraphQL 查询之前,我们需要对每个参数进行适当的验证和过滤操作,在第一个示例中,我们只允许传递字符串类型的参数,其他的参数类型按需进行转化或选择忽略掉。

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

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

3. 使用 GraphQL 鉴权和授权策略

我们针对以上提到的两种风险,保证在 GraphQL 数据查询和突变操作中,实现身份验证和授权策略。身份验证意味着能够验证客户端请求的用户身份。例如为每个请求所附带的 JWT token。如果请求是由未经身份验证的用户发起的,则拒绝响应该请求。授权策略则允许我们控制用户对查询和突变操作的访问权限。例如,我们可以在服务器端定义查询和突变操作的权限。

在客户端,可以将用户 JWT token 作为请求的请求头发送。例如:

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

在服务器端,我们可以在执行查询之前,验证并解码 JWT token,以确定请求的用户身份是否有效。例如,在 ExpressJS 中我们可以编写一个中间件来进行检查,并在请求之前设置用户信息给 resolver:

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

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

在执行查询之后,我们可以检查客户端查询的安全性。通过检查输入中的参数,我们可以对 GraphQL 查询进行足够的验证。例如,在 resolver 函数中,我们应该对 GraphQL 查询参数进行有效性验证,以确保它们符合期望的数据类型,并且没有构成任何安全风险。

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

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

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

总结

GraphQL 的灵活性使其成为前后端开发人员的首选选择。然而,这种灵活性也可能带来安全性问题。本文中,我们介绍了在 GraphQL 中安全处理用户输入的步骤,并提供了几种保护 GraphQL 查询和数据突变免受恶意攻击的策略。请务必注意在 GraphQL 实现中采取合适的安全措施。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64cc201d5ad90b6d04246a24


猜你喜欢

  • ESLint 如何检查函数是否有返回值

    ESLint 是一个开源的 JavaScript 代码检查工具,它能够帮助前端开发者在代码编写过程中发现常见的代码错误,并且还支持多种自定义规则的开发,以适应团队的具体需求。

    1 年前
  • 如何在 Sequelize 中使用事务来控制数据库交易

    在进行数据库交易时,我们经常需要考虑事务的使用。事务可以确保在某些操作失败时回滚所有对数据库的更改,从而避免数据不一致的问题。在 Sequelize 中,我们可以使用事务来控制数据库交易。

    1 年前
  • RxJS 中 zip 的原理及实现方式

    前言 在 RxJS 中,zip 是一个非常有用的操作符,它可以将多个 Observable 按照顺序一一对应,从而得到一个新的 Observable。这个新的 Observable 会在每个源 Obs...

    1 年前
  • Web 与 PWA 架构设计方案比较

    引言 Web 应用一直是互联网世界的重要组成部分,但是原生应用和 PWA 已经在移动端开始逐渐风靡。那么,PWA 和传统的 Web 应用相比,架构设计方案有哪些不同呢?对于前端开发者来说,应该如何根据...

    1 年前
  • ECMAScript 2021(ES12)中Generator的使用详解

    Generator是JavaScript中一个比较特殊的函数,它可以被暂停和恢复,并且可以在不阻塞当前线程的情况下,将反复和异步代码转换为同步代码执行。 在ES6之前,JavaScript中没有这样的...

    1 年前
  • Promise 在 CSS3 动画中的应用实例分享

    在前端动画开发中,我们经常需要运用 CSS3 实现动画效果。但在实际操作过程中,经常会遇到异步的情况,例如当我们需要按顺序加载多个 CSS3 动画时,每个动画结束后,才能顺序执行下一个动画。

    1 年前
  • ES10 采用的新正则特性解析及使用教程

    ES10 采用的新正则特性解析及使用教程 正则表达式是前端开发中常用的一种技术。ES10 中新增了一些新的正则特性,本篇文章就来详细解析这些新特性,并提供相应的使用教程与示例代码。

    1 年前
  • 在 Fastify 框架中使用 Websockets 搭建聊天室

    前言 在前端开发中,使用 Websockets 技术实现实时通讯功能已经成为了一种常见的需求,而 Fastify 是一个高效且易用的 Node.js Web 开发框架,它的设计目标是提供一种基于 Ty...

    1 年前
  • Web Components 实现一个带图片的轮播组件

    Web Components 是一种通过组合原生 HTML、CSS 和 JavaScript 的方式开发可重用的用户界面组件的技术。它使得前端开发人员可以通过封装可重复使用的功能和界面,使得整个项目的...

    1 年前
  • Kubernetes 健康检查回顾

    背景 Kubernetes 是一款流行的容器编排平台,它为我们提供了一个高度自动化的环境来部署、扩展和管理容器化应用程序。然而,保证 Kubernetes 集群中的容器应用程序的健康状态并不总是一件容...

    1 年前
  • 初学 Docker 篇:用 Docker Compose 搭建 Web 服务

    在现代 Web 开发过程中,容器化技术已经成为了一个必不可缺的组成部分。Docker 是一种流行的容器化技术,它可以自动化地打包和部署应用程序及其依赖项。 本文将介绍如何使用 Docker Compo...

    1 年前
  • 构建具有多语言支持的 Angular 应用程序的步骤和技巧

    随着全球化的趋势不断发展,越来越多的企业和组织需要为其应用程序添加多语言支持。在 Angular 中实现多语言支持相对容易,但是需要遵循一些步骤和技巧。在本文中,我们将讨论如何构建具有多语言支持的 A...

    1 年前
  • Next.js 应用如何配置 CDN 加速

    前言 现在的 Web 应用越来越重,引入的依赖多、页面组件多,加载速度逐渐成为用户体验的重要指标。为了提升网站性能,我们可以采用 CDN(内容分发网络)来缓存静态资源并加速访问速度。

    1 年前
  • Mocha 测试框架中如何使用 TypeScript 编写测试代码

    前言 在 Web 前端开发中,测试是至关重要的环节,能够有效保证软件质量,保障软件功能可靠性。而 Mocha是一款使用Javascript编写测试的框架。但是,随着前端项目变得越来越复杂,使用 Jav...

    1 年前
  • Deno 中如何处理 HTTP 请求的错误?

    在 Deno 中,我们可以通过内置的 fetch 函数来进行 HTTP 请求。但是,由于网络传输的不确定性,我们也需要处理 HTTP 请求中可能遇到的错误。 下面,我们将一步步地介绍在 Deno 中如...

    1 年前
  • 如何在 Webpack 中使用 GraphQL?

    如果你是一个前端开发者,你肯定听说过 Webpack 这个强大的构建工具。Webapck 已经成为了前端应用程序开发的标配。GraphQL 也是一个由 Facebook 开发的强大的查询语言, 可以让...

    1 年前
  • Babel 框架升级后出现的 BUG 及解决方案

    1. 背景 随着前端技术的不断发展,新的框架和工具层出不穷。Babel 作为前端开发中广泛使用的语法编译工具,在最近的升级过程中出现了一些 BUG,这给广大开发者带来了一定的困扰。

    1 年前
  • 学习 ES7 的 Array.prototype.fill 方法,让数组填充操作更加简单高效

    介绍 在前端开发中,数组是常用的数据结构之一。数组提供了各种便利的操作方法,其中 fill 方法是 ES7 新增的一个方法。这个方法可以快速、简单地填充数组,提高了数组填充操作的效率和方便性。

    1 年前
  • MongoDB 数据备份和还原方法详解

    MongoDB 是一款非关系型数据库 (NoSQL),由于其高性能、可扩展性和可靠性等特点,已成为 Web 开发领域中备受欢迎的数据库之一。在使用 MongoDB 数据库时,如何进行数据备份和数据还原...

    1 年前
  • ES8 中的 Object.getOwnPropertyDescriptors() 方法控制对象属性行为

    在 JavaScript 中,对象是一等公民。我们可以通过对象来封装数据,定义方法,甚至是创建类和实例。在实际的开发场景中,我们常常需要操作对象的属性,例如获取、添加、修改或者删除属性等。

    1 年前

相关推荐

    暂无文章