如何在next-auth客户端API中添加自定义用户字段并正常渲染
问题根源
你自定义的session回调返回结构不符合NextAuth的接口规范:NextAuth要求session回调直接返回session对象,你额外嵌套了一层session字段,导致getSession最终返回的数据结构变为{ session: { user: {...} } },你原有代码中取session.user实际为undefined,访问属性时就会触发报错。此外你原有代码中查询数据库后没有关闭连接,会导致数据库连接泄露。
修复方案
方案1:快速修复现有逻辑
直接修改session回调的返回逻辑,删除多余的嵌套结构,补充数据库关闭逻辑:
callbacks: { session: async (session) => { if (!session?.user?.email) return session; const client = await connectToDatabase(); const usersCollection = client.db().collection('users'); const userData = await usersCollection.findOne({ email: session.user.email, }); // 补充关闭数据库连接 client.close(); // 直接在原有session对象上扩展字段 session.user.id = userData._id.toString(); session.user.firstname = userData.firstname; session.user.lastname = userData.lastname; session.user.username = userData.username; // 直接返回session对象,不要嵌套外层session return session; }, },
方案2:优化性能(推荐)
你已经开启了JWT模式,可以配合jwt回调把自定义字段存储到JWT令牌中,无需每次获取session都查询数据库:
export default NextAuth({ session: { jwt: true, }, providers: [ // 原有Providers配置保持不变 ], callbacks: { // 登录时触发,将自定义字段存入JWT jwt: async (token, user) => { // 仅首次登录时user参数存在数据 if (user) { token.id = user.id; token.firstname = user.firstname; token.lastname = user.lastname; token.username = user.username; } return token; }, // 读取session时触发,从JWT中提取字段填充到session session: async (session, token) => { if (token) { session.user.id = token.id; session.user.firstname = token.firstname; session.user.lastname = token.lastname; session.user.username = token.username; } return session; } } });
两种方案修改完成后,你原有页面中getSession获取到的session结构就和修改前保持一致,无需修改页面逻辑即可正常读取字段。
内容的提问来源于stack exchange,提问作者Ben Bagley
相关产品推荐
相关产品推荐

