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

如何在tRPC上下文中获取Supabase Auth用户会话数据?

在T3栈的tRPC上下文中获取Supabase Auth会话的正确方法

核心思路

在tRPC的createTRPCContext中,使用Supabase官方的createServerSupabaseClient创建服务器端客户端是标准且合理的做法——因为每个请求的req/res对象不同,需要绑定当前请求上下文来正确处理cookie中的会话信息,并非重复创建冗余实例。

步骤1:在createTRPCContext中获取会话

在你的tRPC上下文定义文件(通常是src/server/api/trpc.ts)中,编写如下代码:

import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { type CreateNextContextOptions } from '@trpc/server/adapters/next';
import { prisma } from '../db'; // 导入你的Prisma客户端

export const createTRPCContext = async (opts: CreateNextContextOptions) => {
  const { req, res } = opts;

  // 创建绑定当前请求的Supabase服务器端客户端
  const supabase = createServerSupabaseClient({ req, res });

  // 获取当前会话
  const { data: { session } } = await supabase.auth.getSession();

  return {
    supabase,
    session,
    prisma, // 把Prisma也传入上下文,方便路由使用
  };
};

步骤2:封装认证中间件(可选但推荐)

创建一个中间件来检查会话是否存在,简化受保护路由的编写:

import { initTRPC, TRPCError } from '@trpc/server';
import { type Context } from './context'; // 导入你定义的上下文类型

const t = initTRPC.context<Context>().create();

// 检查用户是否已认证的中间件
const isAuthed = t.middleware(({ ctx, next }) => {
  if (!ctx.session?.user) {
    throw new TRPCError({ code: 'UNAUTHORIZED' });
  }
  return next({
    ctx: {
      // 细化会话用户的类型,避免后续类型断言
      session: { ...ctx.session, user: ctx.session.user },
    },
  });
});

// 导出公开和受保护的Procedure
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
export const router = t.router;

步骤3:在tRPC路由中使用会话

现在可以在路由中直接通过上下文获取会话,比如:

import { router, publicProcedure, protectedProcedure } from '../trpc';

export const appRouter = router({
  // 公开路由:无需认证即可访问
  getPublicData: publicProcedure.query(() => {
    return { message: '这是公开内容' };
  }),

  // 受保护路由:仅登录用户可访问
  getUserProfile: protectedProcedure.query(async ({ ctx }) => {
    // 直接从上下文获取已认证的用户信息
    const userProfile = await ctx.prisma.user.findUnique({
      where: { id: ctx.session.user.id },
    });
    return userProfile;
  }),
});

export type AppRouter = typeof appRouter;

关键说明

  • createServerSupabaseClient内部会自动处理请求中的cookie,确保会话数据与当前请求绑定,每次请求创建是符合Next.js服务器端逻辑的,不存在冗余问题。
  • 若你担心性能,Supabase的服务器端客户端本身是轻量的,不会带来额外负担。

内容的提问来源于stack exchange,提问作者crevulus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:02:05