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

NextAuth搭配MongoDB刷新页面即登出问题求助

问题原因与解决方法

你的核心问题是服务器端获取会话的方式错误:直接从ctx.req.session读取会话是无效的,NextAuth 要求在服务器端必须通过getServerSession方法来解析并验证会话(尤其是JWT策略下)。

具体修复步骤

1. 导入必要依赖

在authmiddleware.ts和使用中间件的页面中,导入getServerSession和你的NextAuth配置:

// authmiddleware.ts
import { getServerSession } from "next-auth/next";
import { options } from "../pages/api/auth/[...nextauth]"; // 路径需匹配你的文件位置
import { GetServerSidePropsContext } from "next";

2. 修改中间件逻辑

把直接读取req.session的代码替换为getServerSession调用:

// authmiddleware.ts
export async function isLoggedInMiddleware(ctx: GetServerSidePropsContext) {
  const session = await getServerSession(ctx.req, ctx.res, options);
  if (!session || !session.user) {
    ctx.res.writeHead(302, { Location: "/login" });
    ctx.res.end();
    return;
  }
}

export async function isLoggedOutMiddleware(ctx: GetServerSidePropsContext) {
  const session = await getServerSession(ctx.req, ctx.res, options);
  if (session) {
    ctx.res.writeHead(302, { Location: "/" });
    ctx.res.end();
    return;
  }
}

3. 更新页面的getServerSideProps

因为中间件现在是异步函数,getServerSideProps需要加上await调用:

// Login.tsx
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
  await isLoggedOutMiddleware(ctx);
  return {
    props: {},
  };
};

// index.tsx
export const getServerSideProps: GetServerSideProps<Props> = async (ctx) => {
  await isLoggedInMiddleware(ctx);
  // 可选:将会话传递给页面props,让SessionProvider在服务端渲染时就能拿到会话
  const session = await getServerSession(ctx.req, ctx.res, options);
  return {
    props: { session },
  };
};

4. 额外检查项

  • 确保NEXTAUTH_SECRET环境变量已正确设置:生产环境必须使用安全的随机字符串,可用openssl rand -hex 32生成,不能用默认值。
  • 登录逻辑优化:当前用setTimeout跳转不够可靠,建议直接设置signIn的redirect: true,让NextAuth自动处理跳转:
    // Login.tsx 中handleLogin修改
    const response = await signIn("credentials", {
      redirect: true,
      callbackUrl: "/",
      username,
      password
    })
    
    登录成功后会自动跳转到首页,无需手动调用router.push。

原理说明

当使用CredentialsProvider + JWT会话策略时,NextAuth不会自动在req.session中填充数据,必须通过getServerSession验证请求中的JWT令牌、解析出有效会话。直接读取req.session会拿到空值,导致刷新页面后中间件判定用户未登录,触发重定向。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:37:50