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

NextAuth.js + Next.js App Router:如何在中间件中检查用户是否完成引导?

解决NextAuth中间件中检查引导状态的问题

为什么getServerSession会报错?

getServerSession是为Node.js环境的服务器组件/API路由设计的,而Next.js的Middleware运行在边缘Runtime,不支持Node.js专属API,因此无法在Middleware中使用getServerSession,必须改用NextAuth提供的边缘兼容方式获取Session。

正确实现引导状态检查的步骤

1. 自定义NextAuth Middleware(替换原默认导出)

不用直接导出NextAuth的默认Middleware,而是用withAuth包装自定义逻辑,通过req.nextauth获取Session/Token:

import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";

export default withAuth(
  async function middleware(req) {
    const { pathname } = req.nextUrl;
    // 从NextAuth上下文获取Session/Token(v4版本通常用req.nextauth.token)
    const session = req.nextauth.session || req.nextauth.token;

    // 检查用户是否完成引导(假设Session中已携带onboardingCompleted字段)
    const hasCompletedOnboarding = session?.user?.onboardingCompleted;

    // 路由重定向逻辑
    // 已登录但未完成引导,且当前不在引导页 → 跳转到引导页
    if (session && !hasCompletedOnboarding && pathname !== "/onBoarding") {
      return NextResponse.redirect(new URL("/onBoarding", req.url));
    }
    // 已完成引导的用户访问引导页 → 跳转到主页
    if (session && hasCompletedOnboarding && pathname === "/onBoarding") {
      return NextResponse.redirect(new URL("/", req.url));
    }
  },
  {
    // 授权回调:返回true表示用户已登录,进入自定义Middleware逻辑
    callbacks: {
      authorized: ({ token }) => !!token,
    },
  }
);

// 路由匹配规则:排除API和登录页,其他路由都需检查
export const config = {
  matcher: ["/((?!api|login).*)"],
};

2. 将引导状态同步到Session中

为了在Middleware中直接获取引导状态,需要在NextAuth的authOptions里配置jwt和session回调,从MongoDB查询并同步状态到Session:

// authOptions.js(你的NextAuth配置文件)
import { User } from "@/models/User"; // 你的MongoDB用户模型

export const authOptions = {
  // 其他配置(providers、secret等)...
  callbacks: {
    async jwt({ token, user }) {
      // 用户首次登录时,从数据库获取引导状态
      if (user) {
        const dbUser = await User.findById(user.id);
        token.onboardingCompleted = dbUser?.onboardingCompleted || false;
      }
      return token;
    },
    async session({ session, token }) {
      // 将Token中的引导状态同步到Session,供Middleware使用
      session.user.onboardingCompleted = token.onboardingCompleted;
      return session;
    },
  },
};

3. (可选)直接在Middleware中查询MongoDB(不推荐)

如果不想把状态存在Session里,也可以在Middleware中调用内部API查询MongoDB(注意边缘环境的缓存限制):

// 在Middleware中添加查询函数
async function checkOnboardingStatus(userId) {
  const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/check-onboarding`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ userId }),
    cache: "no-store", // 禁用缓存,确保获取最新状态
  });
  const data = await res.json();
  return data.completed;
}

// 在Middleware逻辑中调用
const hasCompletedOnboarding = await checkOnboardingStatus(session.sub);

原pages.newUser配置的替代

NextAuth v4中,pages.newUser已被弃用,改用上述Middleware逻辑实现首次登录后的引导页跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:27:08