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

NextJS 14 + Auth.js v5:凭证登录后Session需手动刷新显示

NextJS 14 + Auth.js v5 凭证登录后Session不自动更新问题

问题现象

  • OAuth(如Github)登录后跳转至设置页,Session自动更新,页面正常展示对应设置选项
  • 凭证(Credentials)登录后跳转至设置页,Session无法自动更新,必须手动刷新页面才能看到完整会话数据

问题原因

Auth.js v5的OAuth登录流程会自动触发客户端Session同步,但凭证登录的signIn方法默认不会主动更新客户端Session状态。同时Root Layout中通过auth()获取的初始Session是服务器端渲染结果,客户端跳转后不会自动重新获取最新Session。

修复方案

1. 凭证登录后手动触发Session更新

在凭证登录的处理逻辑中,登录成功后调用useSession的update方法,确保客户端Session同步:

// 登录组件内的凭证登录处理逻辑
const handleLogin = async () => {
  const result = await signIn("credentials", {
    email: formValues.email,
    password: formValues.password,
    redirect: false, // 关闭自动跳转,手动控制流程
  });

  if (result?.ok) {
    const { update } = useSession();
    update(); // 手动更新客户端Session
    router.push("/settings"); // 跳转至设置页
  }
};

2. 优化用户信息获取钩子

修改useCurrentUser钩子,确保Session加载完成后再返回用户数据:

"use client";

import { useSession } from "next-auth/react";

export const useCurrentUser = () => {
  // 强制等待Session加载完成
  const session = useSession({ required: true });
  return session.data?.user;
};

3. 完善Auth.js的凭证提供者配置

确保凭证登录的authorize方法返回完整用户信息,同时通过JWT回调将用户字段同步到Session中:

// auth.ts 中的配置片段
export const { auth, handlers, signIn, signOut } = NextAuth({
  providers: [
    Credentials({
      credentials: {
        email: { label: "邮箱", type: "email" },
        password: { label: "密码", type: "password" },
      },
      async authorize(credentials) {
        // 验证用户逻辑(示例)
        const user = await getUserByEmail(credentials?.email as string);
        if (!user || !user.password) return null;

        const passwordMatch = await bcrypt.compare(
          credentials?.password as string,
          user.password
        );

        if (passwordMatch) {
          // 返回包含所有必要字段的用户对象
          return {
            id: user.id,
            name: user.name,
            email: user.email,
            role: user.role,
            isOAuth: user.isOAuth,
          };
        }
        return null;
      },
    }),
    // 其他OAuth提供者配置...
  ],
  session: { strategy: "jwt" },
  callbacks: {
    async jwt({ token, user }) {
      // 登录时将用户信息合并到JWT token
      if (user) {
        token.id = user.id;
        token.role = user.role;
        token.isOAuth = user.isOAuth;
      }
      return token;
    },
    async session({ session, token }) {
      // 将JWT中的字段同步到Session用户对象
      if (session.user) {
        session.user.id = token.id as string;
        session.user.role = token.role as string;
        session.user.isOAuth = token.isOAuth as boolean;
      }
      return session;
    },
  },
});

4. 设置页添加Session加载状态处理

在设置页中先判断Session加载状态,避免渲染空数据:

const SettingsPage = () => {
  const user = useCurrentUser();
  const { status } = useSession();

  if (status === "loading") {
    return <div className="text-center py-10">加载中...</div>;
  }

  // 原有渲染逻辑...
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:35:01