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

NextJS中使用sessionStorage实现路由鉴权遇问题求助

在Next.js中使用sessionStorage实现路由鉴权的正确姿势

错误根源

「ReferenceError: sessionStorage is not defined」是因为Next.js的组件会经历**服务器端渲染(SSR)或静态生成(SSG)**阶段,而Node.js环境中不存在浏览器专属的sessionStorage对象——直接在组件顶层、getServerSideProps/getStaticProps这类服务器端执行的代码里访问它,必然报错。


解决方案1:用useEffect确保仅在客户端访问sessionStorage

useEffect的回调函数只会在浏览器端执行,这是访问sessionStorage的安全时机。结合路由跳转逻辑,就能实现客户端鉴权:

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

export default function ProtectedPage() {
  const router = useRouter();
  const [isAuth, setIsAuth] = useState(false);

  useEffect(() => {
    // 仅在客户端执行
    const jwtToken = sessionStorage.getItem('your-jwt-key');
    
    if (!jwtToken) {
      // 无令牌则跳转登录页
      router.push('/login');
      return;
    }

    // 可选:添加令牌有效性校验(比如解码或调用后端接口)
    const isValid = validateToken(jwtToken);
    if (!isValid) {
      sessionStorage.removeItem('your-jwt-key');
      router.push('/login');
      return;
    }

    setIsAuth(true);
  }, [router]);

  // 未完成鉴权时显示加载态,避免服务器端渲染出未授权内容
  if (!isAuth) {
    return <div>验证中...</div>;
  }

  return (
    <div>
      这是仅授权用户可见的页面内容
    </div>
  );
}

// 示例:令牌校验函数(根据实际JWT逻辑实现)
function validateToken(token) {
  try {
    const payload = JSON.parse(atob(token.split('.')[1]));
    return payload.exp * 1000 > Date.now(); // 检查是否过期
  } catch (err) {
    return false;
  }
}

如果可以调整令牌存储方式,优先推荐用HTTP-only Cookie:

  1. 它不会被XSS攻击窃取,安全性更高;
  2. 可以配合Next.js的Middleware在请求到达页面之前完成鉴权,避免客户端加载态闪烁。

示例中间件代码(middleware.js放在项目根目录):

import { NextResponse } from 'next/server';

export function middleware(request) {
  // 从请求头获取Cookie
  const token = request.cookies.get('your-jwt-key');

  // 未登录且访问受保护路由时,重定向到登录页
  if (!token && request.nextUrl.pathname.startsWith('/protected')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // 已登录则允许继续访问
  return NextResponse.next();
}

// 指定需要鉴权的路由
export const config = {
  matcher: ['/protected/:path*'],
};

关于js-cookie无法访问的问题

如果之前在非客户端代码里调用js-cookie(比如组件顶层、服务器端函数),同样会报错。必须把js-cookie的调用放在useEffect或事件回调里:

import Cookies from 'js-cookie';
import { useEffect } from 'react';

useEffect(() => {
  const token = Cookies.get('your-jwt-key');
  // 这里可以正常获取Cookie
}, []);

关键注意事项

  • 所有浏览器专属API(sessionStorage、localStorage、window、document等),只能在客户端执行的代码块中使用:useEffect/useLayoutEffect回调、事件处理函数(如onClick)、客户端组件(Next.js 13+的'use client'组件)。
  • 用sessionStorage做鉴权时,客户端加载态是必要的——否则服务器端渲染的页面会先显示未授权内容,再跳转,影响体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:05:12