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

如何在NextJS页面路由中获取登录用户的ID?

解决方案

要直接在auth()返回的用户对象中获取id字段,你需要通过NextAuth的session回调自定义返回的session内容,同时扩展TypeScript类型以支持自定义字段:

1. 修改auth.ts添加Session回调

在你的auth.ts配置中,添加callbacks.session函数,将数据库用户的id注入到session对象里:

import NextAuth from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
import { authConfig } from './auth.config';
import { z } from 'zod';
import { sql } from '@vercel/postgres';
import type { User } from '@/app/lib/definitions';
import bcrypt from 'bcrypt';

async function getUser(email: string): Promise<User | undefined> {
  try {
    const user = await sql<User>`SELECT * FROM users WHERE email=${email}`;
    return user.rows[0];
  } catch (error) {
    console.error('Failed to fetch user:', error);
    throw new Error('Failed to fetch user.');
  }
}
 
export const { auth, signIn, signOut } = NextAuth({
  ...authConfig,
  callbacks: {
    // 保留原有的authorized回调
    authorized({ auth, request: { nextUrl } }) {
      const isLoggedIn = !!auth?.user;
      const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
      if (isOnDashboard) {
        if (isLoggedIn) return true;
        return false;
      } else if (isLoggedIn) {
        return Response.redirect(new URL('/dashboard', nextUrl));
      }
      return true;
    },
    // 添加session回调,注入用户id
    async session({ session, user }) {
      if (session.user && user.id) {
        session.user.id = user.id;
      }
      return session;
    },
  },
  providers: [
    Credentials({
      async authorize(credentials) {
        const parsedCredentials = z
          .object({ email: z.string().email(), password: z.string().min(6) })
          .safeParse(credentials);
 
        if (parsedCredentials.success) {
          const { email, password } = parsedCredentials.data;
          const user = await getUser(email);
          if (!user) return null;

          const passwordsMatch = await bcrypt.compare(password, user.password);
          if (passwordsMatch){
            return user;
          }
        }
 
        console.log('Invalid credentials');
        return null;
      },
    }),
  ],
});

2. 扩展NextAuth TypeScript类型

由于NextAuth默认的User和Session类型不包含id字段,需要创建类型扩展文件(比如types/next-auth.d.ts)让TypeScript识别自定义字段:

import NextAuth from "next-auth";
import type { User as AppUser } from "@/app/lib/definitions";

declare module "next-auth" {
  // 复用你定义的User类型
  interface User extends AppUser {}

  interface Session {
    user: User;
  }
}

3. 验证效果

修改完成后,重新启动项目,在dashboard/page.tsx中调用auth()就能直接获取包含id的用户对象:

const user = await auth();
console.log(user);
// 输出示例:
// {
//   user: { id: "1", name: 'User toto', email: 'user@nextmail.com' },
//   expires: '2025-01-12T13:47:17.724Z'
// }

原理说明

NextAuth默认只会将name、email、image字段存入session,通过session回调可以将authorize函数返回的完整用户对象中的id(或其他自定义字段)注入到session中,这样后续通过auth()获取session时就能直接拿到这些字段,无需额外查询数据库。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:04:55