Next.js+TRPC Server Component预取受保护接口认证失败求助
核心原因
Next.js的Server Component运行在服务端环境,不像客户端请求会自动由浏览器携带Cookie。当你在Server Component里调用TRPC的受保护接口时,默认的TRPC客户端不会自动把当前请求的Cookie传递给后端,导致Better Auth无法识别用户身份,抛出未认证错误。而客户端渲染完成后,浏览器发起的请求会自动带上Cookie,所以能正常执行。
解决方法
1. 全局配置服务端TRPC客户端自动传递Headers
在TRPC客户端初始化代码中,针对服务端环境从Next.js的headers()方法获取当前请求头,传递给TRPC客户端,避免每次调用都手动传参:
// trpc/server.ts import { createTRPCProxyClient, httpBatchLink } from '@trpc/client'; import { headers } from 'next/headers'; import type { AppRouter } from '../server/router'; export const serverTRPC = createTRPCProxyClient<AppRouter>({ links: [ httpBatchLink({ url: '/api/trpc', headers() { const headerList = headers(); return { cookie: headerList.get('cookie'), }; }, }), ], });
之后在Server Component中直接使用serverTRPC调用接口,即可自动携带当前请求的Cookie。
2. 单个调用时手动传递Headers
如果不需要全局配置,也可以在每次Server Component调用TRPC接口时,手动传入请求头:
// app/protected/page.tsx (Server Component) import { headers } from 'next/headers'; import { trpc } from '@/trpc/client'; export default async function ProtectedPage() { const cookieHeader = headers().get('cookie'); const data = await trpc.protectedApi.query(undefined, { headers: { cookie: cookieHeader, }, }); return <div>{JSON.stringify(data)}</div>; }
3. 配合Better Auth优化服务端验证流程
在TRPC的上下文创建函数中,直接从请求头获取Cookie并初始化Better Auth,确保受保护路由能正确识别用户:
// server/trpc/context.ts import { initAuth } from '@better-auth/react'; import { headers } from 'next/headers'; export async function createContext() { const cookie = headers().get('cookie'); const auth = await initAuth({ headers: { cookie }, }); return { auth, }; }
验证方式
可以在TRPC后端的受保护路由中打印请求头,确认Cookie是否正常传递:
// server/router/protected.ts import { publicProcedure, router } from '../trpc'; export const protectedRouter = router({ protectedApi: publicProcedure.use((opts) => { console.log('请求携带的Cookie:', opts.ctx.req.headers.cookie); // 检查Cookie是否存在 if (!opts.ctx.auth.user) { throw new Error('未认证用户'); } return opts.next(); }).query(() => { return { data: '受保护数据' }; }), });
内容的提问来源于stack exchange,提问作者Ritesh Kumar
相关产品推荐
相关产品推荐

