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

NextAuth保护路由问题:Dashboard页面Session返回Undefined求助

NextAuth Session 始终返回 Undefined 的解决方案

我实现了nextAuthOptions函数,用于接收后端返回的Cookie并存储到浏览器中,但在Dashboard路由验证Session时,Session始终返回Undefined。已查阅官方文档和相关视频仍无法解决,恳请提供解决方案。

相关代码

NextAuth配置文件

export const nextAuthOptions: NextAuthOptionsCallback = (
  req,
  res
): NextAuthOptions => {
  console.log("req", req);
  console.log("res", res);
  return {
    secret: process.env.SECRET,
    providers: [
      Credentials({
        name: "Custom Login",
        credentials: {
          username: {
            label: "Correo:",
            type: "username",
            placeholder: "correo@google.com",
          },
          password: {
            label: "Contraseña:",
            type: "password",
            placeholder: "Contraseña",
          },
        },
        async authorize(credentials) {
          const user = await axiosHttpService.login(
            `http://localhost:3001/api/auth/login`,
            {
              username: credentials!.username,
              password: credentials!.password,
            }
          );
          const cookies = user.headers["set-cookie"];

          res.setHeader("set-cookie", cookies);

          return user.data.data;
        },
      }),
    ],

    session: {
      maxAge: 2592000, /// 30d
      strategy: "jwt",
      updateAge: 86400, // cada día
    },

    pages: {
      signIn: "/login",
    },

    callbacks: {
      async jwt({ token, account, user }) {
        token.accessToken = account?.accessToken;
        token.user = user;

        return token;
      },

      async session({ session, token, user }) {
        session.user = token.user as any;
        return session;
      },
    },
  };
};

export default (req: NextApiRequest, res: NextApiResponse) => {
  return NextAuth(req, res, nextAuthOptions(req, res));
};

Dashboard路由文件

export default function Dashboard() {
  const { data: session } = useSession();

  if (typeof window === "undefined") return null;

  if (session) {
    return (
      <>
        <h1>Protected Page</h1>
        <p>You can view this page because you are signed in.</p>
      </>
    );
  }
  return <p>Access Denied</p>;
}
export async function getServerSideProps(
  context: GetServerSidePropsContext
): Promise<GetServerSidePropsResult<any>> {
  const session = await getServerSession(
    context.req,
    context.res,
    nextAuthOptions(
      context.req as NextApiRequest,
      context.res as NextApiResponse
    )
  );

  return {
    props: {
      session,
    },
  };
}

问题排查与修复方案

1. 确保用户数据包含唯一标识

NextAuth的JWT需要用户数据有唯一标识(如id)才能正确关联Session。如果后端返回的用户数据没有该字段,需手动添加:

async authorize(credentials) {
  const user = await axiosHttpService.login(
    `http://localhost:3001/api/auth/login`,
    {
      username: credentials!.username,
      password: credentials!.password,
    }
  );
  const cookies = user.headers["set-cookie"];
  res.setHeader("set-cookie", cookies);
  
  // 补充唯一id字段,这里用username作为示例
  const userData = { ...user.data.data, id: user.data.data.username };
  return userData;
}

2. 避免动态生成NextAuth配置

每次调用nextAuthOptions生成新配置实例可能导致签名不一致,改为静态配置:

// 修改为静态配置(无需依赖req/res时)
export const nextAuthOptions: NextAuthOptions = {
  secret: process.env.SECRET,
  providers: [
    Credentials({
      // 原有provider配置
      async authorize(credentials) {
        // 原有逻辑
      },
    }),
  ],
  session: {
    maxAge: 2592000,
    strategy: "jwt",
    updateAge: 86400,
  },
  pages: {
    signIn: "/login",
  },
  callbacks: {
    // 优化后的回调逻辑
    async jwt({ token, user }) {
      if (user) token.user = user;
      return token;
    },
    async session({ session, token }) {
      session.user = token.user as any;
      return session;
    },
  },
};

// getServerSideProps中直接使用静态配置
const session = await getServerSession(context.req, context.res, nextAuthOptions);

3. 优化JWT与Session回调逻辑

移除冗余的account处理(Credentials模式下account为空),仅在首次登录时写入用户数据:

callbacks: {
  async jwt({ token, user }) {
    // 仅在用户登录时添加数据到token
    if (user) {
      token.user = user;
    }
    return token;
  },
  async session({ session, token }) {
    // 从token同步用户数据到session
    session.user = token.user as any;
    return session;
  },
}

4. 检查SessionProvider配置

确保_app.tsx中正确包裹SessionProvider,否则客户端useSession无法获取数据:

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

export default function App({ Component, pageProps: { session, ...pageProps } }) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  );
}

5. 验证Cookie有效性

检查后端返回的Cookie是否符合以下要求:

  • Path设置为/,确保全站可访问
  • 域名与前端一致(localhost下无需额外配置)
  • Cookie未被浏览器拦截(可在浏览器DevTools的Application面板查看)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:57:03