Next.js项目:提交表单后无需重登更新NextAuth的session.user值
解决方案:无需重新登录更新NextAuth Session用户信息
问题核心:NextAuth采用JWT存储session数据,JWT是静态令牌,登录后生成的token不会自动同步数据库的用户信息更新,因此需要手动触发session更新并同步JWT中的数据。
1. 前端表单提交后触发Session更新
在用户提交姓名修改表单、数据库更新成功后,使用useSession返回的update方法同步新的用户信息到session:
import { useSession } from "next-auth/react"; export default function ProfileForm() { const { data: session, update } = useSession(); const handleSubmit = async (e) => { e.preventDefault(); const formData = new FormData(e.target); const updatedFirstname = formData.get('firstname'); const updatedLastname = formData.get('lastname'); // 调用API更新数据库 const updateRes = await fetch('/api/update-profile', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ firstname: updatedFirstname, lastname: updatedLastname }) }); if (updateRes.ok) { // 同步新信息到session await update({ user: { ...session.user, firstname: updatedFirstname, lastname: updatedLastname } }); } }; return ( <form onSubmit={handleSubmit}> <input type="text" name="firstname" defaultValue={session?.user?.firstname} required /> <input type="text" name="lastname" defaultValue={session?.user?.lastname} required /> <button type="submit">更新姓名</button> </form> ); }
2. 修改NextAuth配置,支持JWT更新
更新[...nextauth].js中的jwt回调,处理session更新请求时同步token内的用户信息:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; const SECRET_KEY = process.env.JWT_SECRET_KEY; export default NextAuth({ providers: [ CredentialsProvider({ name: "credentials", async authorize(credentials) { // 数据库连接与密码验证逻辑 // ... const returnObject = { firstname: user.firstname, lastname: user.lastname, email: user.email, }; return returnObject; }, }), ], callbacks: { jwt: async ({ token, user, trigger, session }) => { // 登录时初始化用户信息到token if (user) { token.user = user; } // 处理session更新请求,同步新用户信息到token if (trigger === "update" && session?.user) { token.user = { ...token.user, ...session.user }; } return token; }, session: async ({ session, token }) => { // 从token同步最新用户信息到session session.user = token.user; return session; }, }, secret: SECRET_KEY, jwt: { secret: SECRET_KEY, encryption: true, }, session: { jwt: true, }, pages: { signIn: "/auth/login", }, });
3. 数据库更新API路由示例
如果尚未创建更新数据库的API,可参考以下示例(以Prisma ORM为例):
// pages/api/update-profile.js import { getServerSession } from "next-auth/next"; import { authOptions } from "./auth/[...nextauth]"; import prisma from "../../lib/prisma"; export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ message: "Method Not Allowed" }); } const session = await getServerSession(req, res, authOptions); if (!session) { return res.status(401).json({ message: "Unauthorized" }); } const { firstname, lastname } = req.body; try { await prisma.user.update({ where: { email: session.user.email }, data: { firstname, lastname }, }); res.status(200).json({ firstname, lastname }); } catch (error) { res.status(500).json({ message: "Failed to update profile" }); } }
完成以上配置后,用户提交表单更新姓名后,session会立即刷新,头部组件通过useSession获取到最新的用户信息,无需重新登录即可显示更新后的姓名。
内容的提问来源于stack exchange,提问作者Ar4mus
相关产品推荐
相关产品推荐

