Next-Auth getSession在middleware.js中返回null的问题求助
解决Next-Auth Middleware中getSession返回null的问题
核心问题分析
- 导入错误:你在middleware中使用的
getSession来自next-auth/react,这个方法是为客户端React组件设计的,无法在Edge Runtime环境的middleware中正确获取会话。 - Middleware冲突:同时导出默认的
next-auth/middleware和自定义middleware会导致Next.js只执行其中一个,逻辑无法正常触发。
步骤1:抽离NextAuth配置
修改[...nextauth].js,将认证配置单独导出,方便middleware复用:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import bcrypt from "bcryptjs"; import { connectDB } from "@/backend/utils/dbConnect"; import prisma from "@/prisma/prismaClient"; // 单独导出auth配置 export const authOptions = { providers: [ CredentialsProvider({ name: "credentials", credentials: {}, async authorize(credentials, req) { const { identifier, password } = credentials; try { await connectDB(); const user = await prisma.users.findFirst({ where: { OR: [{ email: identifier }, { phone: identifier }], }, }); if (!user) return null; const passwordMatching = await bcrypt.compare(password, user.password); return passwordMatching ? user : null; } catch (error) { return null; } }, }), ], session: { strategy: "jwt", maxAge: 7 * 24 * 60 * 60, expires: 30 * 24 * 60 * 60, }, callbacks: { async jwt({ token, user }) { if (user) token.user = user; return token; }, async session({ session, token }) { session.user.id = token.user.id; session.user.role = token.user.role; delete session.user.email; delete session.user.phone; delete session.user.password; return session; }, }, pages: { signIn: "/login", }, secret: process.env.NEXTAUTH_SECRET, }; export const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
步骤2:重构Middleware代码
删除默认的next-auth middleware导出,改用getServerSession(服务端/Edge环境专用)获取会话,并完善跳转逻辑:
import { NextResponse } from "next/server"; import { getServerSession } from "next-auth/next"; import { authOptions } from "@/app/api/auth/[...nextauth]"; // 根据你的项目路径调整 export const config = { matcher: ["/admin/:path*", "/donor/:path*", "/login"], }; const roleRedirects = { admin: "/admin", donor: "/donor", }; export async function middleware(request) { const session = await getServerSession(authOptions); const role = session?.user?.role; const { pathname } = request.nextUrl; // 已登录用户访问登录页,跳转到对应角色仪表盘 if (session && pathname === "/login") { return NextResponse.redirect(new URL(roleRedirects[role], request.url)); } // 未登录用户访问权限页,跳转到登录页 if (!session && (pathname.startsWith("/admin") || pathname.startsWith("/donor"))) { return NextResponse.redirect(new URL("/login", request.url)); } // 已登录用户访问非自身角色的权限页,跳转到自己的仪表盘 if (session && role) { const allowedPath = roleRedirects[role]; if (!pathname.startsWith(allowedPath)) { return NextResponse.redirect(new URL(allowedPath, request.url)); } } return NextResponse.next(); }
额外检查项
- 确保
NEXTAUTH_SECRET环境变量已正确配置,JWT会话的解析依赖此密钥。 - 确认数据库返回的用户对象包含
role字段,且在jwt和session回调中正确传递。 - 验证middleware文件路径是否符合Next.js要求:App Router项目中需放在根目录或
app目录下。
内容的提问来源于stack exchange,提问作者Md Injamul
相关产品推荐
相关产品推荐

