使用Next-Auth中间件登录后仍重定向至登录页的问题排查
我使用Next-Auth中间件保护指定页面,已按官方文档完成配置,未登录状态下会正确重定向到登录页,但登录后系统依然将我重定向至登录页,求排查问题原因。
相关代码
[...nextauth].ts
import NextAuth, { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import client from "@/libs/server/client"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import { Session } from "next-auth/"; interface UserSession extends Session { id: string; } export const authOptions: NextAuthOptions = { // Configure one or more authentication providers adapter: PrismaAdapter(client), providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }), ], callbacks: { session: ({ session, user }) => { (session as UserSession).id = user.id; return session; }, redirect: ({ url, baseUrl }) => { return baseUrl; }, }, secret: process.env.NEXTAUTH_SECRET, pages: { signIn: "/enter", }, }; export default NextAuth(authOptions);
middleware.ts
export { default } from "next-auth/middleware"; export const config = { matcher: ["/mypage","/with", "/product/:path*"], };
排查方向与解决方法
1. 修正redirect回调的逻辑问题
你当前的redirect回调直接返回baseUrl,完全覆盖了Next-Auth登录后的默认重定向逻辑——原本登录成功后应跳转到用户之前访问的受保护页面,现在被强制跳转到根目录,甚至可能干扰会话状态的验证流程。
修改redirect回调,保留默认重定向逻辑:
redirect: ({ url, baseUrl }) => { // 若目标URL属于当前站点,直接返回该URL;否则返回站点根目录 return url.startsWith(baseUrl) ? url : baseUrl; },
如果不需要自定义重定向,直接移除该回调即可。
2. 确认NEXTAUTH_URL环境变量配置正确
NEXTAUTH_URL是Next-Auth生成会话Cookie、回调地址的核心配置,必须与站点实际地址一致:
- 开发环境:
http://localhost:3000 - 生产环境:你的实际域名(如
https://yourdomain.com)
若该变量配置错误,中间件无法正确识别用户的登录会话,会持续判定用户未登录并重定向到登录页。
3. 验证数据库会话记录是否正常生成
使用Prisma Adapter时,登录成功后数据库中应生成对应的User和Session记录。直接查看数据库表,确认:
- 用户登录后
User表新增了对应账号的记录 Session表存在有效的会话数据
如果会话记录未生成,说明Prisma连接或Adapter配置有问题,需检查数据库连接字符串是否正确,以及Prisma Client是否正常初始化。
4. 适配Cookie配置(跨域/子域名场景)
如果站点使用子域名或跨域部署,需确保Next-Auth的Cookie配置适配场景。可在authOptions中添加Cookie配置:
cookies: { sessionToken: { name: `__Secure-next-auth.session-token`, options: { domain: process.env.NEXT_PUBLIC_APP_DOMAIN, // 填写你的站点域名 path: "/", sameSite: "lax", httpOnly: true, secure: process.env.NODE_ENV === "production", }, }, },
错误的Cookie域名或SameSite设置会导致浏览器无法携带会话Cookie,中间件无法识别登录状态。
5. 确认登录页未被中间件拦截
检查middleware.ts的matcher数组,确保自定义登录页/enter不在匹配规则中。当前配置是正确的,但后续修改规则时,要避免将登录页加入受保护列表,否则会出现登录页被拦截的死循环。
内容的提问来源于stack exchange,提问作者d-caffein

