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; } }
解决方案2:改用HTTP-only Cookie + 中间件(更安全+无闪烁)
如果可以调整令牌存储方式,优先推荐用HTTP-only Cookie:
- 它不会被XSS攻击窃取,安全性更高;
- 可以配合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
相关产品推荐
相关产品推荐

