【免费下载链接】graphql-yoga
🧘 Rewrite of a fully-featured GraphQL Server with focus on easy setup, performance & great developer experience. The core of Yoga implements WHATWG Fetch API and can run/deploy on any JS environment.
项目地址:
https://gitcode.com/gh_mirrors/gr/graphql-yoga
点击查看 免费下载
本篇以 GraphQL Yoga 仓库中的 examples/graphql-armor 示例为主体,讲解如何把 GraphQL Armor 这一基于 Envelop 的安全中间件集成进 createYoga 创建的服务器,实现对恶意或异常 GraphQL 请求的拦截。读完本文,你将能够在本仓库示例基础上独立配置 Armor 插件、理解其插件注入 Envelop 编排器的底层链路,并通过 curl 与集成测试验证各项防护措施的生效效果。
示例定位与快速上手
examples/graphql-armor 是一个可独立运行的最小化示例,其 package.json 中的描述为 "Adding security layer to GraphQL Yoga using GraphQL Armor"。目录结构非常简洁:
- examples/graphql-armor/src/yoga.ts:创建 Yoga 实例并挂载 Armor 插件;
- examples/graphql-armor/src/main.ts:基于 node:http 启动 HTTP 服务;
- examples/graphql-armor/integration-tests/graphql-armor.spec.ts:验证防护行为的集成测试。
在仓库根目录执行以下命令即可启动示例服务(该示例通过 pnpm workspace 的 –filter 定位到 example-graphql-armor 包):
pnpm –filter example-graphql-armor start
服务启动后监听 4000 端口,端点为 /graphql(见 examples/graphql-armor/src/main.ts 中的 server.listen(4000, …) 与 yoga.graphqlEndpoint 拼接日志)。其依赖锁定为 @escape.tech/graphql-armor@3.1.7、graphql@17.0.2 与 workspace 内的 graphql-yoga(见 examples/graphql-armor/package.json),因此本文描述的行为均以此为适用前提。
核心实现:把 Armor 插件交给 createYoga
示例的核心代码在 examples/graphql-armor/src/yoga.ts:
import { versionInfo } from 'graphql';
import { createSchema, createYoga, Plugin } from 'graphql-yoga';
import { EnvelopArmor } from '@escape.tech/graphql-armor';
const armor = new EnvelopArmor();
const enhancements = armor.protect();
export const yoga = createYoga({
plugins: [
…enhancements.plugins,
// In GraphQL>=17 we have the `hideSuggesstions` option instead.
…(versionInfo.major >= 17
? [
{
onValidate(params) {
params.setValidationFn((s, d, r, options) =>
params.validateFn(s, d, r, { …options, hideSuggestions: true }),
);
},
} satisfies Plugin,
]
: []),
],
schema: createSchema({
typeDefs: /* GraphQL */ `
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`,
resolvers: {
Query: {
books: () => booksStore,
},
},
}),
});
这段代码包含三层关键信息:
Armor 插件为何能直接注入 Yoga
createYoga 的 plugins 参数接受的就是 Envelop 插件。从 packages/graphql-yoga 的入口 packages/graphql-yoga/src/index.ts 可以看到,Yoga 直接透传了 @envelop/core 的 envelop、useEnvelop、useExtendContext 等核心能力,并导出了 Plugin 类型(packages/graphql-yoga/src/plugins/types.js)。因此 enhancements.plugins 与普通 Yoga 内置插件处于同一执行链上:每个插件的 onValidate、onExecute 等钩子都会被 Envelop 编排器统一调度。
校验函数的替换机制可在 Envelop 核心源码中印证。packages/envelop/core/src/orchestrator.ts 中,编排器维护一个可变的 validateFn(初始为 graphql 包导出的 validate),并通过 onValidate 钩子参数暴露 setValidationFn 供插件替换,最终执行校验时调用的是被替换后的 validateFn。示例中 GraphQL 17 分支里 params.setValidationFn(…) 正是利用这一机制,在不修改 Armor 输出的前提下追加 hideSuggestions 选项。
支持的安全措施
README 声明该示例(配合 Armor 默认配置)覆盖以下整改措施(remediations):
- Aliases Limit:限制别名数量,防止通过海量别名放大执行成本;
- Character Limit:限制查询文档总字符数,拦截超长查询;
- Cost Limit:按查询复杂度成本进行限制;
- Depth Limit:限制查询字段嵌套深度,防止深层嵌套拖垮执行;
- Directives Limit:限制指令(directive)使用数量;
- Disabled Field Suggestion:在"字段不存在"的校验错误中屏蔽字段建议,避免借助拼错字段名的报错逐字探测 schema。
这些措施对应 Armor 自身的配置项,示例中 new EnvelopArmor() 使用的是其内置默认阈值;如需调整(如放宽 maxDepth、关闭某项防护),可在 EnvelopArmor 构造函数的配置对象中修改,本仓库示例未展开这部分,需参照 Armor 项目自身的文档。
防护效果验证
合法查询应正常通过
对端点发起合法查询,应返回数据而非被 Armor 拦截:
$ curl –location –request POST 'http://localhost:4000/graphql' \\
–header 'Content-Type: application/json' \\
–data-raw '{"query":"query { books { title } }"}'
{"data":{"books":[{"title":"The Awakening"},{"title":"City of Glass"}]}}
字段建议被屏蔽
故意查询一个不存在的字段 titlee(README 原文写作 title[e],示例 payload 实为 titlee):
$ curl –location –request POST 'http://localhost:4000/graphql' \\
–header 'Content-Type: application/json' \\
–data-raw '{"query":"query { books { titlee } }"}'
{"data":null,"errors":[{"message":"Cannot query field \\"titlee\\" on type \\"Book\\". [Suggestion message hidden by GraphQLArmor]?","locations":[{"line":1,"column":17}],"extensions":{}}]}
错误消息中原本 graphql-js 会附带的 "Did you mean title?" 建议被屏蔽——这正是 Disabled Field Suggestion 的价值:攻击者无法通过拼错字段名再读取建议来无成本地枚举 schema。
集成测试对行为的固化
examples/graphql-armor/integration-tests/graphql-armor.spec.ts 通过 yoga.fetch(…) 直接对内存中的 Yoga 实例发起请求,覆盖两个断言:
这段测试也解释了 README 中 curl 输出与测试快照在措辞上的细微差异:两者分别对应 Armor 的提示替换与 GraphQL 17 原生隐藏建议两种实现路径。
小结与使用要点
- 集成成本极低:new EnvelopArmor() + armor.protect().plugins 展开进 createYoga 的 plugins 即完成接入,示例完整实现不足 60 行(examples/graphql-armor/src/yoga.ts);
- 插件生效依赖 Yoga 对 Envelop 钩子的原生调度,setValidationFn 机制的底层实现见 packages/envelop/core/src/orchestrator.ts;
- 当前仓库锁定的依赖版本为 @escape.tech/graphql-armor@3.1.7、graphql@17.0.2;若你使用 graphql 16,行为会走 Armor 自身的建议屏蔽路径,若使用 17 及以上,则如示例所示叠加原生 hideSuggestions;
- 示例默认阈值适用于演示,生产环境建议结合自身查询复杂度与业务特征显式配置各项 limit,并通过类似本示例的集成测试固化防护行为,防止回归。
赞
【免费下载链接】graphql-yoga
🧘 Rewrite of a fully-featured GraphQL Server with focus on easy setup, performance & great developer experience. The core of Yoga implements WHATWG Fetch API and can run/deploy on any JS environment.
项目地址:
https://gitcode.com/gh_mirrors/gr/graphql-yoga
点击查看 免费下载
相关推荐
Chroma常见问题解答:解决开发中遇到的典型问题
GitHub Training Kit项目管理:GitHub Professional Services团队的工作方法
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网硕互联帮助中心






评论前必须登录!
注册