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

Next.js 14.0.4:登出后点击浏览器返回按钮仍可访问受保护路由

Next.js 14登出后浏览器返回仍可访问受保护路由的解决方案

问题现象

使用Next.js 14.0.4开发时,用户登出后点击浏览器返回按钮仍能访问/dashboard等受保护路由,但手动输入该路由地址时,中间件可正常拦截并跳转,控制台无报错。

问题原因

浏览器返回按钮加载的是缓存的页面快照,不会触发服务器端的中间件登录状态校验;而手动输入地址会发起全新HTTP请求,会经过中间件的检查逻辑。

修复方案

1. 客户端组件添加登录状态校验

在/dashboard/page.js等受保护路由的组件中,添加客户端校验逻辑,确保页面挂载时强制检查登录状态:

'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';

export default function Dashboard() {
  const router = useRouter();
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  useEffect(() => {
    // 读取登录状态Cookie
    const loggedinCookie = document.cookie.split('; ')
      .find(row => row.startsWith('loggedin='))?.split('=')[1];
    
    if (!loggedinCookie) {
      // 未登录则跳转首页
      router.replace('/');
    } else {
      setIsLoggedIn(true);
    }
  }, [router]);

  if (!isLoggedIn) {
    return null; // 或显示加载占位符
  }

  return (
    <div>你的Dashboard内容</div>
  );
}

2. 修正中间件代码错误

你的中间件存在端口混用(3001/3000)的问题,同时建议使用Next.js官方推荐的nextUrl对象处理路由,避免直接拼接字符串:

import { NextResponse } from "next/server";

export default function middleware(req) {
  const verify = req.cookies.get("loggedin");
  const nextUrl = req.nextUrl;

  // 拦截未登录用户访问受保护路由
  if (!verify && nextUrl.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/", req.url));
  }

  // 已登录用户访问首页时跳转至Dashboard
  if (verify && nextUrl.pathname === "/") {
    return NextResponse.redirect(new URL("/dashboard", req.url));
  }
}

// 指定中间件生效的路由范围,提升性能
export const config = {
  matcher: ["/", "/dashboard/:path*"],
};

3. 优化登出逻辑

登出时使用router.replace替换浏览器历史记录,避免后退回到受保护路由:

'use client';

import { useRouter } from 'next/navigation';

export function LogoutButton() {
  const router = useRouter();

  const handleLogout = () => {
    // 清除登录Cookie
    document.cookie = "loggedin=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
    // 替换历史记录跳转首页
    router.replace('/');
  };

  return <button onClick={handleLogout}>登出</button>;
}

方案说明

  • 客户端组件校验:即使浏览器加载缓存页面,组件挂载时也会执行登录状态检查,确保未登录用户无法停留。
  • 修正后的中间件:使用nextUrl更可靠,matcher配置减少不必要的中间件执行。
  • router.replace:覆盖历史记录中的受保护路由条目,点击返回时会回到更早的页面(如登录页),而非Dashboard。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 14:21:10