后端API设计【免费下载链接】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-helix-auth0示例为核心讲解如何在不依赖任何 Web 框架内置认证机制的前提下用 Envelop 的envelop/auth0插件为 GraphQL-Helix Fastify 搭建的服务添加基于 JWT 的 Auth0 认证。读者将掌握 Auth0 API/应用的完整配置流程、useAuth0插件的全部核心参数及其底层实现原理并能将同一套认证方案迁移到 Envelop 支持的任何 HTTP 集成场景中。示例定位在 GraphQL-Helix 之上叠加 Auth0 认证仓库中的 graphql-helix-auth0 示例 是在graphql-helix基础示例见 examples/envelop/graphql-helix/README.md之上演示如何用envelop/auth0插件为请求增加认证能力。这里有三层技术栈需要先厘清EnvelopGraphQL 服务器无关的插件化执行层。它把parse、validate、execute、subscribe、context 构建等环节抽象成可插拔的钩子让认证、日志、追踪等横切能力可以附着在任何 HTTP 框架上。GraphQL-Helix抽象了 HTTP 执行的 GraphQL 请求处理流程。它提供getGraphQLParameters、processRequest、sendResult、shouldRenderGraphiQL、renderGraphiQL等工具函数使同一套执行逻辑可以轻松支持多种传输层。envelop/auth0Envelop 的认证插件。它校验 Auth0 签发的 JWT并把解析出的用户信息注入 GraphQL context详见 插件文档。示例选用 Fastify 作为 HTTP 服务器最终效果是未携带令牌的请求访问authInfo字段得到null携带合法 Bearer 令牌的请求则能拿到 Auth0 用户的唯一标识sub。安装依赖与前置条件在 Envelop 工程中安装认证插件示例的依赖清单可参考 examples/envelop/graphql-helix-auth0/package.jsonnpm i envelop/auth0除envelop/auth0外示例还依赖envelop/core、graphql-tools/schema、fastify、graphql与graphql-helix。运行方式有两种在仓库根目录用pnpm安装全部依赖进入 examples/envelop/graphql-helix-auth0 目录执行pnpm run start该目录的package.json中start脚本为ts-node index.ts然后打开http://localhost:3000/graphql。在代码层面动手之前需要先在 Auth0 控制台完成两项配置一个API提供domain与audience两个关键值和一个Application用于在浏览器端换取访问令牌。这两项配置的完整细节在 envelop-website/content/docs/guides/adding-authentication-with-auth0.mdx 有逐步演示下面按顺序展开。第一步把 useAuth0 接入 EnvelopuseAuth0是一个标准的 Envelop 插件把它与useSchema一起放入envelop({ plugins: [...] })即可import * as GraphQLJS from graphql import { useAuth0 } from envelop/auth0 import { envelop, useEngine, useSchema } from envelop/core const getEnveloped envelop({ plugins: [ useEngine(GraphQLJS), useSchema(schema), useAuth0({ domain: {account_name}.{region}.auth0.com, audience: http://localhost:3000/graphql, extendContextField: auth0 }) ] })三个最核心的配置项domainAuth0 服务器的域名即你期望与之通信完成用户认证的 Auth0 tenant 地址格式为{account_name}.{region}.auth0.com。audienceAPI 的标识符。Auth0 用它判定当前令牌是为哪个 API 签发的。若 API 托管在http://localhost:3000/graphql就传入这个 URL。extendContextField认证成功后JWT 的解析结果会被注入 context 对象的该字段名下后续在 resolver 中通过context.auth0读取例如context.auth0.sub。第二步在 Auth0 控制台创建 API 并取得 domain 与 audience在 Auth0 控制台登录后进入 Dashboard → APIs 页面点击Create API创建一个 APIName随意命名示例使用Envelop Demo。Identifier设置为 GraphQL API 的 URL本地示例为http://localhost:3000/graphql生产环境应换成生产服务器的 URL。Signing Algorithm保持默认即可。创建完成后audience就等于刚才填写的 Identifierhttp://localhost:3000/graphqldomain隐藏在 API 详情页的Test标签页中形如{account_name}.{region}.auth0.com。把这两个值填回useAuth0的配置中。需要特别留意的是envelop/auth0要求domain不带协议前缀源码中插件会自动拼接https://与/.well-known/jwks.json来拉取 JWKS详见下文源码解析。第三步在 Schema 中暴露认证信息为了让客户端能查到认证结果需要在 GraphQL Schema 中添加相应类型。示例使用graphql-tools/schema的makeExecutableSchema定义const schema makeExecutableSchema({ typeDefs: /* GraphQL */ Describes the authentication object as provided by Auth0. type AuthenticationInfo { String that uniquely identifies an authenticated user. sub: String! } type Query { The authentication information of the request. authInfo: AuthenticationInfo } , resolvers: { Query: { authInfo(_source, _args, context) { return context.auth0 } } } })这里的AuthenticationInfo只暴露了subAuth0 用户唯一标识resolver 直接把插件注入的context.auth0原样返回。启动服务器后在 GraphiQL 中执行query { authInfo { sub } }由于尚未携带任何认证头结果中authInfo为null——这正是未认证时的预期行为。第四步生成访问令牌——创建 Auth0 应用与登录路由要拿到真实的 JWT 访问令牌需要创建 Auth0Application在 Auth0 控制台的Applications页面点击Create application命名例如Envelop Example Single Page Web应用类型选择Single Page Web Applications进入应用详情页记录Client ID在Settings标签页中把Allowed Callback URLs、Allowed Logout URLs、Allowed Web Origins均设为应用地址http://localhost:3000并保存。随后在 Fastify 中新增一个根路由用 Auth0 SPA SDK通过 CDN 引入完成登录并取回令牌。这段逻辑在 示例入口 中是这样实现的app.route({ method: GET, url: /, async handler(req, res) { res.header(Content-Type, text/html; charsetUTF-8) res.send(/* HTML */ !DOCTYPE html / html head script srchttps://cdn.auth0.com/js/auth0-spa-js/1.12/auth0-spa-js.production.js/script /head body script createAuth0Client({ domain: {account_name}.{region}.auth0.com, client_id: client_id, audience: http://localhost:3000/graphql }).then(async auth0 { await auth0.loginWithPopup() const accessToken await auth0.getTokenSilently() window.document.body.innerText accessToken }) /script /body /html ) } })重启服务并访问http://localhost:3000/后会弹出 Auth0 登录窗口登录成功后将页面中显示的访问令牌复制下来。这里只是一个最小可行的演示——在实际前端工程中应当用 Auth0 SDK 与框架组件如 Next.js 的nextjs-auth0集成并把令牌保存在内存或安全存储中随每个 GraphQL 请求发送。第五步发送带认证的请求回到 GraphiQL切换到Request Headers标签页写入{ Authorization: Bearer access token }重新执行同一条查询返回结果即为{ data: { authInfo: { sub: google-oauth2|101177380012777232372 } } }从null到sub的成功返回说明 JWT 已被服务端成功校验用户身份已被解析并注入 context。服务端接线全景index.ts 逐段拆解示例的完整实现位于 examples/envelop/graphql-helix-auth0/index.ts它演示了 Envelop 与 GraphQL-Helix 如何协作。核心步骤如下1. 装配 Envelop。envelop()接收parse、validate、execute、subscribe四个 GraphQL 执行函数并挂载useSchema与useAuth0两个插件const getEnveloped envelop({ parse, validate, execute, subscribe, plugins: [ useSchema(schema), useAuth0({ domain: auth0Config.domain, audience: auth0Config.audience, extendContextField: auth0, }), ], })2. 在请求处理函数中按请求构建执行环境。每次请求到来时调用getEnveloped({ req })得到与本次请求绑定的parse、validate、contextFactory、execute、schema。这正是 Envelop 的每个请求一个执行环境模型——认证信息就是在这个阶段通过 context 构建被注入的。3. 用 GraphQL-Helix 处理 HTTP 语义。将 Fastify 的req.body、req.headers、req.method、req.query组装成 GraphQL-Helix 需要的request对象再用shouldRenderGraphiQL判断是否返回 GraphiQL 界面、用getGraphQLParameters解析操作、用processRequest执行、用sendResult(result, res.raw)回写响应app.route({ method: [GET, POST], url: /graphql, async handler(req, res) { const { parse, validate, contextFactory, execute, schema } getEnveloped({ req }) const request { body: req.body, headers: req.headers, method: req.method, query: req.query, } if (shouldRenderGraphiQL(request)) { res.type(text/html) res.send(renderGraphiQL({})) } else { const { operationName, query, variables } getGraphQLParameters(request) const result await processRequest({ operationName, query, variables, request, schema, parse, validate, execute, contextFactory, }) sendResult(result, res.raw) res.sent true } }, })其中contextFactory由 Envelop 生成GraphQL-Helix 会在执行前调用它得到完整 context——这也是useAuth0注入的context.auth0能出现在 resolver 中的原因。源码级解析useAuth0 的内部工作方式useAuth0的实现位于 packages/envelop/plugins/auth0/src/index.ts其认证链路可以分为三个阶段令牌提取。默认的extractTokenFn会从 context 中查找req或request属性再从其中的headers读取authorization头可用headerName覆盖并按Bearer token的形式拆分出令牌令牌类型可用tokenType覆盖默认Bearer。头不存在时返回null格式非法会抛出错误。若你的框架没有把请求放进 context插件会打印警告此时应提供自定义extractTokenFn。签名校验。插件基于JWKSJSON Web Key Set标准校验令牌const jkwsClient new JwksRsa.JwksClient({ cache: true, rateLimit: true, jwksRequestsPerMinute: 5, jwksUri: https://${options.domain}/.well-known/jwks.json, ...options.jwksClientOptions, })即先decode令牌取出头部中的kidKey ID再用它向https://{domain}/.well-known/jwks.json获取对应的公钥最后用jsonwebtoken的verify以RS256算法校验签名、audience和issuerhttps://{domain}/。默认启用 JWKS 客户端缓存与限流每分钟 5 次请求可通过jwksClientOptions覆盖。注入 context。校验通过后插件在onContextBuilding钩子中调用extendContext({ [contextField]: decodedPayload })把解码后的 payload含sub挂到 context 上若未配置令牌且preventUnauthenticatedAccess为true则抛出UnauthenticatedError阻断执行。关键配置项速查与默认值结合 插件文档 与源码完整配置项如下配置项默认值说明domain必填Auth0 域名不带协议前缀如my-domain.us.auth0.comaudience必填Auth0 API 标识符即 API IdentifierextendContextField_auth0认证成功后 payload 注入 context 的字段名文档推荐设为auth0headerNameauthorization读取令牌的请求头名称tokenTypeBearer期望的令牌类型前缀preventUnauthenticatedAccessfalse源码默认不抛错为true时未认证请求直接抛错为false时 context 中该字段为nullonError(error)默认直接抛出认证失败时的错误处理回调可自定义客户端看到的错误extractTokenFn(context)内置提取逻辑自定义令牌提取函数接收已构建的 context 作为参数jwksClientOptions内置cache、rateLimit、5 次/分钟透传jwks-rsa的 JwksClient 选项jwtVerifyOptions内置RS256、audience、issuer透传jsonwebtoken的verify选项jwtDecodeOptions内置透传decode阶段的选项一个值得注意的实践细节文档原话客户端必须配置audience字段否则 Auth0 会签发 opaque token 而非 JWT导致服务端无法按预期校验。进阶用 useExtendContext 加载完整用户档案useAuth0只负责身份认证你是谁完整的注册/资料流程还需要持久化。指南给出的推荐做法是在 Schema 中通过registermutation 之类的操作落库然后在 context 构建阶段用useExtendContext见 插件文档把数据库中的完整用户对象挂到 contextimport * as GraphQLJS from graphql import { useAuth0 } from envelop/auth0 import { envelop, useEngine, useExtendContext, useSchema } from envelop/core const getEnveloped envelop({ plugins: [ useEngine(GraphQLJS), useSchema(schema), useAuth0(auth0Config), useExtendContext(async context { if (context.auth0) { return { user: await context.db.loadUserBySub(context.auth0.sub) } } return {} }) ] })useExtendContext的实现packages/envelop/core/src/plugins/use-extend-context.ts同样挂在onContextBuilding钩子上接收当前 context 并返回要扩展的字段。注意插件执行顺序useAuth0先运行所以useExtendContext中能读到context.auth0.sub来查询用户。这样resolver 中就能通过context.user访问完整档案而无需在每个 resolver 里重复做令牌解析。小结通过graphql-helix-auth0示例可以完整看到一条HTTP 请求 → Envelop context 构建 → Auth0 JWT 校验 → 用户信息注入 → resolver 消费的认证链路。其核心价值在于认证逻辑被完全收敛在 Envelop 插件层无论底层是 Fastify GraphQL-Helix还是 Express、AWS Lambda、Cloudflare Workers 等任何 Envelop 支持的集成方式useAuth0的接入方式都保持一致。若需在生产环境中使用请重点确认audience配置正确、preventUnauthenticatedAccess按需开启并通过onError与自定义extractTokenFn适配你的错误处理与请求上下文结构。赞分享后端API设计【免费下载链接】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 示例解析:用 Pothos Envelop GraphQL Helix 在 Fastify 上构建类型安全 GraphQL 服务GraphQL Yoga 示例解析:用 Pothos Envelop GraphQL Helix 在 Fastify 上构建类型安全 GraphQL 服后端API设计GraphQL Yoga 仓库实战基于 Envelop 与 graphql-ws 构建 WebSocket GraphQL 订阅服务GraphQL Yoga 仓库实战基于 Envelop 与 graphql ws 构建 WebSocket GraphQL 订阅服务 本文以 graphql后端API设计TypeGraphQL 与 Envelop 集成实战基于 graphql-yoga 仓库示例的插件式 GraphQL 服务端搭建TypeGraphQL 与 Envelop 集成实战基于 graphql yoga 仓库示例的插件式 GraphQL 服务端搭建 本篇以 examples/e后端API设计上一篇终极AI提示词库指南揭秘GitHub推荐项目system_prompts_leaks完全解析下一篇Calibre 30 多种格式互转与书库管理免费教程从首次入库到批量转换的完整操作创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考