You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+TRPC Server Component预取受保护接口认证失败求助

解决方案:Next.js Server Component预取TRPC受保护接口丢失Cookie问题

核心原因

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 00:35:54