已认证用户访问自定义登录页无法重定向的问题
已认证用户访问/login路由时中间件重定向失效的解决方法
问题分析
你当前的中间件使用withAuth包裹,但手动调用getToken获取认证状态的方式存在冗余,且withAuth的默认逻辑会干扰重定向判断,导致已认证用户访问/login时,自定义的重定向逻辑未被正确触发。
解决方案
方案1:利用withAuth自带的认证状态(推荐)
withAuth会自动将认证后的token传递给中间件函数,无需手动调用getToken,同时通过authorized回调调整默认拦截规则,确保已认证用户能进入/login路由后再触发重定向:
import { withAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default withAuth( function middleware(req) { // 已认证用户访问/login时直接重定向到首页 if (req.nextUrl.pathname.startsWith("/login") && req.nextauth.token) { return NextResponse.redirect(new URL("/", req.url)); } }, { pages: { signIn: "/login", }, callbacks: { authorized: ({ token, req }) => { // 允许已认证用户访问/login路由,后续由自定义逻辑处理重定向 if (req.nextUrl.pathname.startsWith("/login")) return true; // 其他路由(如首页)要求用户必须已认证 return !!token; }, }, } ); export const config = { matcher: ["/", "/login"], };
方案2:不依赖withAuth,手动实现完整逻辑
如果需要完全自主控制认证判断逻辑,可以直接编写独立中间件,避免withAuth默认规则的干扰:
import { getToken } from "next-auth/jwt"; import { NextResponse } from "next/server"; export async function middleware(req) { const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET }); const isAuthenticated = !!token; const pathname = req.nextUrl.pathname; // 已认证用户访问/login,重定向到首页 if (pathname.startsWith("/login") && isAuthenticated) { return NextResponse.redirect(new URL("/", req.url)); } // 未认证用户访问首页,重定向到登录页 if (pathname === "/" && !isAuthenticated) { return NextResponse.redirect(new URL("/login", req.url)); } // 其他情况允许正常访问 return NextResponse.next(); } export const config = { matcher: ["/", "/login"], };
关键说明
- 方案1通过
authorized回调放行已认证用户访问/login,避免withAuth默认拦截该路由,确保自定义重定向逻辑能执行。 - 方案2完全手动处理认证状态判断和路由跳转,更适合需要添加复杂自定义规则的场景。
- 确保项目中已正确配置
NEXTAUTH_SECRET环境变量,否则getToken无法正常解析JWT令牌。
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

