开发工具后端API设计【免费下载链接】graphql-playground GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs collaboration)项目地址https://gitcode.com/gh_mirrors/gr/graphql-playground点击查看免费下载graphql-playground-middleware-express 是 GraphQL Playground 项目提供的 Express 中间件用于在 Express 应用中暴露一个路由向浏览器返回 GraphQL Playground IDE 的完整 HTML 页面。本文以该中间件仓库当前版本 1.7.22为核心完整覆盖其安装、最小接入、全部配置项、底层实现原理以及官方重点提示的 XSS 反射漏洞修复与升级方案帮助读者在自己的 Express GraphQL 服务上快速、安全地集成 Playground。中间件定位一行代码挂载 GraphQL IDEGraphQL Playground 是一个图形化 GraphQL IDE支持交互式文档、订阅与协作。graphql-playground-middleware-express的作用是把 Playground 的 HTML 页面含样式、脚本与初始化配置通过 Express 路由输出给浏览器。它本身不解析 GraphQL 请求只负责渲染 IDE 页面真正的 GraphQL 端点由你的应用另行提供。源码中对它的类型定义也印证了这一点——它就是一个标准的 Express 请求处理器export type ExpressPlaygroundMiddleware ( req: Request, res: Response, next: () void, ) void参见 packages/graphql-playground-middleware-express/src/index.ts。安装官方 README 同时提供了 yarn 与 npm 两种方式yarn add graphql-playground-middleware-express或npm install graphql-playground-middleware-express --save从仓库内 package.json 可以看到该包的实际依赖关系与运行前提peerDependenciesexpress: ^4.16.2即要求宿主应用使用 Express 4.x 4.16.2dependenciesgraphql-playground-html: ^1.6.29页面渲染能力全部来自这个底层包包体仅发布dist目录主入口为dist/index.js类型声明为dist/index.d.ts。最小接入示例README 给出的最小用法如下const express require(express) const expressPlayground require(graphql-playground-middleware-express) .default const app express() app.get(/playground, expressPlayground({ endpoint: /graphql }))注意两点必须取.default该包以 ES 模块风格导出CommonJS 环境下需通过.default取到真正的中间件函数endpoint指向你的 GraphQL 端点Playground 页面加载后所有查询/订阅请求都会发往该地址。启动后访问http://localhost:port/playground即可打开 IDE。完整可运行示例结合 Apollo Server仓库的 examples/basic/index.js 提供了一个完整的可运行示例——用apollo-server-express起一个 GraphQL 服务再用本中间件暴露 Playgroundconst express require(express) const { ApolloServer, gql } require(apollo-server-express) const expressPlayground require(../../dist/index).default const typeDefs gql type Query { hello: String! } schema { query: Query } const resolvers { Query: { hello: () world, }, } const PORT 4000 const server new ApolloServer({ typeDefs, resolvers }) const app express() server.applyMiddleware({ app }) app.get( /playground, expressPlayground({ endpoint: /graphql//scriptscriptalert(1)/scriptscript, }), ) app.listen(PORT) console.log( Serving the GraphQL Playground on http://localhost:${PORT}/playground, )运行方式见 examples/basic/README.md$ yarn $ node index.js该示例的endpoint故意写成了一段 XSS 载荷/scriptscriptalert(1)/script这是官方用于验证与演示安全修复的用例——在已修复的版本中这段输入会被清洗后安全输出不会执行脚本。它恰好演示了下一节要讲的配置项与安全机制。配置项详解MiddlewareOptions中间件接收的唯一参数是一个 options 对象其完整类型定义在底层包 packages/graphql-playground-html/src/render-playground-page.ts 中配置项类型说明endpointstringGraphQL 端点地址Playground 默认请求目标subscriptionEndpointstringWebSocket 订阅端点兼容旧写法subscriptionsEndpoint会被自动转换并过滤workspaceNamestring工作区名称envany环境标识传入react或electron时不注入 CDN 资源configanyGraphQL 配置如 .graphqlconfig 内容传入后会被序列化为configString注入页面settingsPartialISettingsIDE 初始设置见下方设置表schemaIntrospectionResult预置的 introspection 结果{ __schema: any }可离线渲染文档tabsTab[]预置的标签页每个 Tab 含endpoint、query、name、variables、responses、headerscodeThemeEditorColours代码编辑器配色属性、注释、关键字、字符串等各 token 颜色其中settings支持的内置键ISettings接口见 render-playground-page.ts设置键类型 / 取值说明general.betaUpdatesboolean是否启用 beta 更新editor.cursorShapeline \| block \| underline光标形状editor.themedark \| light主题editor.reuseHeadersboolean是否跨请求复用请求头tracing.hideTracingResponseboolean是否隐藏 tracing 响应tracing.tracingSupportedboolean是否支持 tracingeditor.fontSizenumber编辑器字号editor.fontFamilystring编辑器字体request.credentialsstring请求凭证模式request.globalHeaders{ [key: string]: string }全局请求头schema.polling.enableboolean是否启用 schema 轮询schema.polling.endpointFilterstring轮询端点过滤schema.polling.intervalnumber轮询间隔底层原理中间件如何生成 Playground 页面中间件本体express 侧packages/graphql-playground-middleware-express/src/index.ts 中的实现非常精简const express: Register function voyagerExpress(options: MiddlewareOptions) { return (req, res, next) { res.setHeader(Content-Type, text/html) const playground renderPlaygroundPage(options) res.write(playground) res.end() } }流程即设置Content-Type: text/html→ 调用graphql-playground-html的renderPlaygroundPage(options)生成完整 HTML → 写入响应并结束。注意next参数被保留但未调用说明该中间件设计为路由终点。页面渲染html 侧renderPlaygroundPage的实现见 packages/graphql-playground-html/src/render-playground-page.ts关键步骤兼容处理旧字段subscriptionsEndpoint会被转换为subscriptionEndpoint并过滤传入config时序列化为configString。缺参告警若endpoint与configString都为空会向控制台输出告警WARNING: You didnt provide an endpoint and dont have a .graphqlconfig. Make sure you have at least one of them.注入配置将完整 options 以 JSON 形式写入div idplayground-config该 div 默认display: none页面加载后由GraphQLPlayground.init(root, JSON.parse(configText))读取并初始化 IDE。加载动画页面中预置了来自 get-loading-markup.ts 的加载容器含 SVG Logo 与一系列淡入/缩放动画window.onload后通过添加fadeOut类淡出。CDN 资源默认从//cdn.jsdelivr.net/npm拉取graphql-playground-react包的build/static/css/index.css与build/static/js/middleware.js传入faviconUrl可自定义 favicon。安全须知XSS 反射漏洞务必阅读官方 README 在显著位置给出了安全警告在1.7.16之前的版本中如果直接把未经清洗的用户输入传给expressPlayground()存在安全漏洞。仓库的 SECURITY.md 与 docs/security/2020-xss-template-injection.md 记录了完整细节。漏洞影响范围漏洞根源在graphql-playground-html的renderPlaygroundPage波及所有下游调用方。官方给出的受影响与修复版本对照graphql-playground-html1.6.22 起安全graphql-playground-express1.7.16 起安全graphql-playground-koa1.6.15 起安全graphql-playground-hapi1.6.13 起安全graphql-playground-lambda1.7.17 起安全漏洞本质是 XSS 反射攻击攻击者可把恶意脚本注入endpoint、settings等任何会被渲染进 HTML 的参数可能导致数据或凭证泄露、系统被破坏。安全与不安全的写法对比静态输入所有版本都安全// expressPlayground 静态 endpoint app.get(/playground, (req) expressPlayground({ endpoint: /our/graphql, settings: { editor.theme: req.query.darkMode ? dark : light }, }), )未清洗的用户输入修复前有漏洞// endpoint 直接拼接路由参数 app.get(/playground/:id, (req) expressPlayground({ endpoint: /our/graphql/${req.params.id}, }), ) // settings 直接取查询参数 app.get(/playground, (req) expressPlayground({ endpoint: /our/graphql, settings: { editor.fontFamily: req.query.font }, }), )注意不只是endpoint任何来自用户的输入如 settings 值都可能成为注入点。升级步骤yarnyarn add graphql-playground-express^1.7.16npmnpm install --save graphql-playground-express^1.7.16修复实现源码如何清洗输入当前版本renderPlaygroundPage在 render-playground-page.ts 中使用xss包对用户可控字段做统一过滤const filter (val) { return filterXSS(val, { whiteList: [], stripIgnoreTag: true, stripIgnoreTagBody: [script] }) }whiteList: []不允许任何 HTML 标签白名单保留stripIgnoreTag: true剥离无法识别的标签stripIgnoreTagBody: [script]直接移除script标签的整个内容体。endpoint、subscriptionEndpoint、favicon、CDN URL 等字段在渲染前都会经过filter见 render-playground-page.ts依赖xss^1.0.6见 packages/graphql-playground-html/package.json。这正是前文示例中那段/scriptscriptalert(1)/script载荷会被无害化的原因。无法升级时的规避方案官方建议在应用层自行清洗用户输入推荐使用与官方相同的xss包。例如const express require(express) const { filterXSS } require(xss) const expressPlayground require(graphql-playground-middleware-express) .default const app express() const filter (val) filterXSS(val, { whitelist: [], stripIgnoreTag: true, stripIgnoreTagBody: [script] }) // 简单示例过滤路径参数 app.get(/playground/:id, (req) expressPlayground({ endpoint: /graphql/${filter(req.params.id)} }) ) // 进阶示例整体清洗 query 对象 app.get(/playground, (req) expressPlayground(JSON.parse(filter(JSON.stringify(req.query)))) )仓库还提供了一份可运行的 XSS 攻击示例与 PoC见 packages/graphql-playground-html/examples/xss-attack含 README 与可执行脚本。最佳实践小结版本确保graphql-playground-middleware-express 1.7.16当前仓库版本为 1.7.22永远不要把未清洗的请求参数req.params、req.query、req.body等直接传入expressPlayground()的任意字段endpoint与config至少提供其一否则 Playground 页面会因缺少目标端点而无法正常工作浏览器控制台会收到官方告警Playground 中间件只负责渲染 IDEGraphQL 请求处理请交给你的 GraphQL 服务器如 Apollo Server若需要自定义页面标题、favicon、预置标签页或主题通过title、faviconUrl、tabs、settings、codeTheme等扩展字段传入即可。关联资源中间件实现packages/graphql-playground-middleware-express/src/index.ts页面渲染与配置类型packages/graphql-playground-html/src/render-playground-page.ts页面入口导出packages/graphql-playground-html/src/index.ts加载动画 markuppackages/graphql-playground-html/src/get-loading-markup.ts完整可运行示例packages/graphql-playground-middleware-express/examples/basic/index.jsXSS 漏洞详情docs/security/2020-xss-template-injection.md已知漏洞索引SECURITY.md赞分享开发工具后端API设计【免费下载链接】graphql-playground GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs collaboration)项目地址https://gitcode.com/gh_mirrors/gr/graphql-playground点击查看免费下载相关推荐提升 WordPress 主题代码质量PHPCS、ESLint 与 wp-scripts 完整工作流指南提升 WordPress 主题代码质量PHPCS、ESLint 与 wp scripts 完整工作流指南 WordPress 主题 _sUnderscore后端前端VLA-Adapter Pro版本全面评测从97.8%到99.6%的性能飞跃VLA Adapter Pro版本全面评测从97.8%到99.6%的性能飞跃 在人工智能与机器人技术飞速发展的今天VLA Adapter Pro版本以其惊人人工智能具身智能机器人微调在 Express 中集成 GraphQL Playground基础示例、中间件原理与安全实践在 Express 中集成 GraphQL Playground基础示例、中间件原理与安全实践 GraphQL Playground 是面向 GraphQL开发工具后端API设计上一篇BMAD-METHOD与GitHub Actions集成自动化版本管理与发布流程下一篇MMKV社区版与企业版对比功能与服务差异创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?