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

NextAuth+NextJS授权后访问受保护页面仍跳转登录的问题

问题分析与解决

这个问题的核心是客户端导航时NextAuth的Session状态未及时同步,导致中间件在页面跳转时仍认为用户未授权,刷新页面后服务端重新验证Session才恢复正常。以下是针对性的修复方案:

方案1:登录后手动触发Session同步

修改登录表单的提交逻辑,禁用自动跳转,确认登录成功后手动刷新Session再跳转:

// LoginForm组件内的提交函数
import { signIn } from 'next-auth/react';

const handleSubmit = async (e) => {
  e.preventDefault();
  const result = await signIn('credentials', {
    email: emailValue,
    password: passwordValue,
    redirect: false, // 关闭自动跳转
  });

  if (result?.ok) {
    // 手动刷新Session后跳转首页
    window.location.href = '/';
  } else {
    // 处理登录失败提示
    alert('账号或密码错误');
  }
};

方案2:优化NextAuth的Session配置

在authOptions中调整JWT和Session的刷新策略,确保客户端状态及时同步:

export const authOptions: NextAuthOptions = {
  // ...其他原有配置
  session: {
    strategy: 'jwt',
    maxAge: 30 * 24 * 60 * 60, // Session有效期30天
    updateAge: 60 * 60, // 每小时自动刷新一次Session
  },
  jwt: {
    maxAge: 30 * 24 * 60 * 60, // JWT有效期30天
  },
  // ...其他原有配置
};

方案3:修改中间件逻辑兼容回调跳转

自定义中间件,当已登录用户访问带callbackUrl的登录页时,直接重定向到目标页面:

// middleware.js
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 { pathname } = req.nextUrl;
  const callbackUrl = req.nextUrl.searchParams.get('callbackUrl');

  // 已登录用户访问带回调的登录页,直接跳转到目标页面
  if (token && pathname === '/' && callbackUrl) {
    return NextResponse.redirect(new URL(callbackUrl, req.url));
  }

  // 未登录用户访问受保护页面,跳转到登录页
  if (!token && (pathname === '/product' || pathname === '/shipping')) {
    return NextResponse.redirect(new URL(`/?callbackUrl=${encodeURIComponent(req.url)}`, req.url));
  }

  return NextResponse.next();
}

export const config = { matcher: ['/product','/shipping', '/'] };

方案4:客户端页面添加Session加载判断

在受保护页面的客户端组件中,先确认Session加载完成再渲染内容:

// /product/page.jsx
'use client';

import { useSession } from 'next-auth/react';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function ProductPage() {
  const { data: session, status } = useSession();
  const router = useRouter();

  useEffect(() => {
    if (status === 'unauthenticated') {
      router.push('/');
    }
  }, [status, router]);

  if (status === 'loading') {
    return <div>加载中...</div>;
  }

  return <div>产品页面内容</div>;
}

内容的提问来源于stack exchange,提问作者Дима Куринной

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:05:17