使用AuthJS扩展session.user对象时遭遇TypeError问题求助
扩展NextAuth Session.user对象时的类型错误问题
问题代码
尝试扩展NextAuth的session.user对象添加自定义字段,代码如下:
import "next-auth"; import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import type { NextAuthConfig } from "next-auth"; declare module "next-auth" { interface User { group: string; avatar: string; } } export const config = { pages: { signIn: "/signin", }, providers: [ CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email", placeholder: "Email (@mobifone.vn)", }, password: { label: "Password", type: "password" }, }, async authorize(credentials) { const authResponse = await fetch( "http://localhost:9000/api/v1/auth/signin", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username: credentials.email, password: credentials.password, }), } ); if (!authResponse.ok) { return null; } const res = await authResponse.json(); return res.user; }, }), ], callbacks: { async session({ session, token, user }) { return { ...session, user: { ...session.user, group: user.group, avatar: user.avatar, }, }; }, }, } satisfies NextAuthConfig; export const { handlers, auth, signIn, signOut } = NextAuth(config);
错误信息
Type '({ session, token, user }: { session: Session; token: JWT; user: AdapterUser; } & { newSession: any; trigger: "update"; }) => Promise<{ user: { group: string; avatar: string; id?: string | undefined; name?: string | ... 1 more ... | undefined; email?: string | ... 1 more ... | undefined; image?: string | ... 1 more ...' is not assignable to type '(params: { session: Session; token: JWT; user: AdapterUser; } & { newSession: any; trigger: "update"; }) => Awaitable<Session | DefaultSession>'. Type 'Promise<{ user: { group: string; avatar: string; id?: string | undefined; name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }; expires: string; }>' is not assignable to type 'Awaitable<Session | DefaultSession>'. Type 'Promise<{ user: { group: string; avatar: string; id?: string | undefined; name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }; expires: string; }>' is not assignable to type 'PromiseLike<Session | DefaultSession>'. Types of property 'then' are incompatible. Type '<TResult1 = { user: { group: string; avatar: string; id?: string | undefined; name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }; expires: string; }, TResult2 = never>(onfulfilled?: ((value: { ...; }) => TResult1 | PromiseLike<...>) | ... 1 more ... | undefined,...' is not assignable to type '<TResult1 = Session | DefaultSession, TResult2 = never>(onfulfilled?: ((value: Session | DefaultSession) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1 more ... | undefined) => PromiseLike<...>'. Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. Types of parameters 'value' and 'value' are incompatible. Type '{ user: { group: string; avatar: string; id?: string | undefined; name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }; expires: string; }' is not assignable to type 'Session | DefaultSession'. Type '{ user: { group: string; avatar: string; id?: string | undefined; name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }; expires: string; }' is not assignable to type 'DefaultSession'. The types of 'user.id' are incompatible between these types. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.ts(2322)
无效尝试
尝试手动添加id字段隐藏错误,但无法完成登录:
callbacks: { async session({ session, token, user }) { return { ...session, user: { ...session.user, id: user.id, group: user.group, avatar: user.avatar, }, }; }, },
解决方案
1. 完整扩展TypeScript接口
不仅要扩展User接口,还要扩展Session接口,确保session.user的类型与DefaultSession兼容,且自定义字段类型正确:
import "next-auth"; import type { DefaultSession } from "next-auth"; declare module "next-auth" { interface User { id: string; // 确保User包含id字段,与后端返回一致 group: string; avatar: string; } interface Session { user: { group: string; avatar: string; } & DefaultSession["user"]; // 合并默认User字段,保证id、name等字段类型正确 } }
2. 正确同步用户信息到Session
Credentials模式下,用户信息会先存入JWT Token,再同步到Session。依赖session回调中的user参数不可靠(仅登录首次回调存在),需通过jwt回调中转:
callbacks: { // 将自定义字段存入JWT Token async jwt({ token, user }) { if (user) { token.id = user.id; token.group = user.group; token.avatar = user.avatar; } return token; }, // 从Token同步字段到Session async session({ session, token }) { if (session.user) { session.user.id = token.id as string; session.user.group = token.group as string; session.user.avatar = token.avatar as string; } return session; }, },
3. 确保后端返回字段完整
确认/api/v1/auth/signin接口返回的res.user包含id、group、avatar三个必填字段,否则TypeScript会在authorize函数中报错。
内容的提问来源于stack exchange,提问作者Minh Thông
相关产品推荐
相关产品推荐

