如何将Auth0的ID token传递给GraphQL Code Generator?
实现方案
你可以通过修改GraphQL Code Generator配置,使用通用fetcher模式灵活适配客户端和服务端两种场景,实现Auth0 token的自动注入,步骤如下:
步骤1:修改codegen.yml配置
将原配置中config.fetcher字段改为generic模式,生成的hooks会将fetcher作为可传入参数,不再硬编码请求逻辑:
overwrite: true schema: http://localhost:4000/graphql generates: src/lib/__generated__/graphql.ts: documents: - "**/graphql/**/*.graphql" - "!mysqldata/**" plugins: - add: content: "/* DO NOT EDIT! this file was generated by graphql-codegen */\n/* eslint-disable */" - typescript - typescript-operations - typescript-react-query config: fetcher: generic # 替换原有fetcher配置为通用模式 reactQueryVersion: 4 # 填写你实际使用的React Query版本
修改后重新执行codegen命令生成新的SDK代码。
步骤2:客户端场景适配(配合auth0-react)
封装一个带Auth0 token注入的fetcher钩子,在客户端组件调用生成的query时传入即可:
// src/hooks/useGraphqlFetcher.ts import { useAuth0 } from '@auth0/auth0-react'; export const useGraphqlFetcher = () => { const { getIdTokenClaims } = useAuth0(); return async <TData, TVariables>( query: string, variables?: TVariables ): Promise<TData> => { // 拿到ID token const claims = await getIdTokenClaims(); const idToken = claims?.__raw || ''; // 发起请求 const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/graphql`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', Authorization: idToken ? `Bearer ${idToken}` : undefined, }, body: JSON.stringify({ query, variables }), }); const json = await res.json(); // 错误处理 if (json.errors?.length) throw new Error(json.errors[0].message); return json.data; }; };
调用示例:
import { useGetUserQuery } from '@/lib/__generated__/graphql'; import { useGraphqlFetcher } from '@/hooks/useGraphqlFetcher'; const UserProfile = () => { const fetcher = useGraphqlFetcher(); // 传入自定义fetcher即可自动注入token const { data, isLoading } = useGetUserQuery(undefined, { fetcher }); // 业务逻辑 };
步骤3:服务端场景适配(配合nextjs-auth0)
在Next.js的API路由或getServerSideProps中,拿到session的ID token后直接构造fetcher传入即可:
// 示例:在getServerSideProps中调用 import { getSession } from '@auth0/nextjs-auth0'; import { getUser } from '@/lib/__generated__/graphql'; export const getServerSideProps = async ({ req, res }) => { const session = getSession(req, res); const idToken = session?.idToken || ''; // 构造服务端fetcher const serverFetcher = async <TData, TVariables>(query: string, variables?: TVariables): Promise<TData> => { const fetchRes = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/graphql`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', Authorization: idToken ? `Bearer ${idToken}` : undefined, }, body: JSON.stringify({ query, variables }), }); const json = await fetchRes.json(); if (json.errors?.length) throw new Error(json.errors[0].message); return json.data; }; // 调用生成的查询方法 const userData = await getUser({}, serverFetcher); return { props: { userData } }; };
内容的提问来源于stack exchange,提问作者user16985789
相关产品推荐
相关产品推荐

