使用Apollo Client+NextAuth从Hasura取数时JWT验证失败求助
解决Apollo Client携带NextAuth Token访问Hasura的JWT验证错误
错误根源分析
你遇到的Invalid number of parts: Expected 3 parts; got 5错误,本质是传给Hasura的不是标准三段式JWT。NextAuth默认的Session Token是自身加密格式(多段结构),不符合Hasura对JWT的解析要求,导致验证失败。
解决方案步骤
1. 配置NextAuth生成Hasura兼容的JWT
在NextAuth的配置文件([...nextauth].ts)中,通过jwt和session回调生成并传递符合Hasura要求的JWT:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import jwt from "jsonwebtoken"; export default NextAuth({ providers: [ CredentialsProvider({ async authorize(credentials) { // 替换为你的用户验证逻辑(比如数据库校验) return { id: "1", email: "user@example.com" }; }, }), // 若使用OAuth提供商(如Google/Auth0),需在这里配置对应Provider ], callbacks: { async jwt({ token, user }) { // 用户首次登录时,生成Hasura专用JWT if (user) { const hasuraJwt = jwt.sign( { sub: user.id, email: user.email, "https://hasura.io/jwt/claims": { "x-hasura-allowed-roles": ["user"], "x-hasura-default-role": "user", "x-hasura-user-id": user.id, }, }, process.env.HASURA_JWT_SECRET!, // 需与Hasura配置的密钥一致 { expiresIn: "1d", algorithm: "HS256" } // 算法需匹配Hasura的JWT设置 ); token.hasuraToken = hasuraJwt; } return token; }, async session({ session, token }) { // 将Hasura JWT注入Session,供前端调用 session.hasuraToken = token.hasuraToken; return session; }, }, });
2. 配置Apollo Client正确携带Hasura JWT
修改Apollo Client的请求拦截逻辑,从NextAuth Session中获取专用的Hasura Token并添加到请求头:
import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; import { getSession } from "next-auth/react"; const httpLink = createHttpLink({ uri: process.env.NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT, }); const authLink = setContext(async (_, { headers }) => { const session = await getSession(); // 注意:这里取的是session.hasuraToken,不是NextAuth默认的session.token const token = session?.hasuraToken; return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); export default client;
3. 验证Hasura的JWT配置
确保Hasura的环境变量HASURA_GRAPHQL_JWT_SECRET格式正确,且与NextAuth中使用的密钥、算法一致:
- 若使用HS256算法,配置示例:
{"type":"HS256","key":"your-shared-secret-key"} - 若使用RS256,需配置公钥字段
关键检查点
- 登录后打印前端Session,确认
hasuraToken是三段式字符串(用.分隔) - 用jwt.io解析
hasuraToken,检查https://hasura.io/jwt/claims字段是否包含正确的角色配置 - 确认Hasura控制台中,对应角色拥有目标数据的访问权限
内容的提问来源于stack exchange,提问作者Yuki Sakiyama
相关产品推荐
相关产品推荐

