概述
本文档介绍 T3 Stack 项目中的会话认证实现方案,基于 NextAuth.js v5 与 tRPC 的集成。
核心组件
┌─────────────────────────────────────────────────────┐
│ NextAuth.js │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ OAuth │ │ Credentials│ │ Session │ │
│ │ Providers│ │ Provider │ │ Management │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ tRPC │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Context │ │ Procedure│ │ Middleware │ │
│ │ (user) │ │ (protected)│ │ (auth check) │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────┘
会话策略配置
// auth.ts
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
// OAuth providers (GitHub, Google, etc.)
],
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id;
}
return token;
},
async session({ session, token }) {
if (session.user) {
session.user.id = token.id as string;
}
return session;
},
},
});
tRPC 集成
// server/api/trpc.ts
export const createTRPCContext = async (opts: { headers: Headers }) => {
const session = await auth();
return {
session,
db: prisma,
};
};
export const protectedProcedure = publicProcedure.use(({ ctx, next }) => {
if (!ctx.session?.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
...ctx,
session: ctx.session,
},
});
});
常见问题
1. Session 未定义
检查 auth() 是否在 API 路由或 Server Component 中调用。
2. JWT 过期处理
配置 pages: { signIn: '/auth/signin' } 自动重定向。
更新记录
- 2026-05-22 v0.1: 初始化文档