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

Next.js中如何访问localStorage数据?React转Next.js开发者求助

解决方案

1. 限制localStorage操作仅在客户端执行

Next.js服务端渲染阶段不存在window对象(localStorage是浏览器API),直接调用会报错。你可以通过两种方式确保代码只在客户端运行:

方式一:使用useEffect钩子

useEffect的回调会在客户端渲染完成后执行,天然避开服务端环境:

import { useEffect } from 'react';

const Login = () => {
  const handleLogin = async (credentials) => {
    const res = await fetch('/api/login', {
      method: 'POST',
      body: JSON.stringify(credentials),
      headers: { 'Content-Type': 'application/json' }
    });
    const { token } = await res.json();

    // 仅在客户端存储token
    if (typeof window !== 'undefined') {
      localStorage.setItem('auth-token', token);
    }
  };

  // 获取token时同样做客户端判断
  useEffect(() => {
    const token = localStorage.getItem('auth-token');
    if (token) {
      // 执行身份验证后续逻辑
    }
  }, []);

  return <button onClick={() => handleLogin({ username, password })}>登录</button>;
};

方式二:判断window是否存在

在任何可能访问localStorage的代码前,先检查window对象是否存在:

// 存储token
if (typeof window !== 'undefined') {
  localStorage.setItem('auth-token', token);
}

// 获取token
const token = typeof window !== 'undefined' ? localStorage.getItem('auth-token') : null;

2. 改用Cookie存储token(适配SSR场景)

如果需要在服务端渲染时获取用户身份(比如页面初始化时请求用户数据),localStorage无法满足需求,因为服务端无法读取浏览器的localStorage。此时推荐用Cookie存储token:

步骤1:登录接口设置Cookie

在pages/api/login.js中,验证用户后将token写入Cookie(建议设置HttpOnly、Secure属性提升安全性):

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { username, password } = req.body;
    // 模拟用户验证逻辑
    const isValid = username === 'admin' && password === '123456';
    if (!isValid) return res.status(401).json({ msg: '验证失败' });

    const token = '生成的JWT或自定义token';
    // 设置Cookie:HttpOnly防止XSS攻击,Secure仅在HTTPS下传输
    res.setHeader('Set-Cookie', `auth-token=${token}; HttpOnly; Secure; Path=/; SameSite=Strict`);
    res.status(200).json({ success: true });
  }
}

步骤2:服务端读取Cookie验证

在getServerSideProps中直接从请求对象读取Cookie,完成身份验证后传递数据给页面:

export async function getServerSideProps(context) {
  const token = context.req.cookies['auth-token'];
  
  // 未登录则重定向到登录页
  if (!token) {
    return { redirect: { destination: '/login', permanent: false } };
  }

  // 用token请求用户数据
  const userRes = await fetch('https://your-api.com/user', {
    headers: { Authorization: `Bearer ${token}` }
  });
  const user = await userRes.json();

  return { props: { user } };
}

3. 使用NextAuth.js简化身份验证

如果不想手动实现复杂的会话管理,Next.js官方推荐的NextAuth.js可以一站式解决客户端/服务端身份验证问题,支持多种登录方式(账号密码、OAuth等):

步骤1:安装依赖并配置路由

npm install next-auth

创建pages/api/auth/[...nextauth].js:

import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

export default NextAuth({
  providers: [
    CredentialsProvider({
      async authorize(credentials) {
        // 调用你的登录接口验证用户
        const res = await fetch('/api/login', {
          method: 'POST',
          body: JSON.stringify(credentials),
          headers: { 'Content-Type': 'application/json' }
        });
        const user = await res.json();
        
        if (user) return user;
        return null;
      }
    })
  ],
  session: { strategy: 'jwt' }, // 用JWT存储会话
  callbacks: {
    async jwt({ token, user }) {
      if (user) token.accessToken = user.token;
      return token;
    },
    async session({ session, token }) {
      session.accessToken = token.accessToken;
      return session;
    }
  }
});

步骤2:在组件中使用会话

import { useSession, signIn, signOut } from 'next-auth/react';

const Profile = () => {
  const { data: session } = useSession();
  
  if (!session) return <button onClick={() => signIn()}>登录</button>;
  
  return (
    <div>
      <p>欢迎,{session.user.name}</p>
      <button onClick={() => signOut()}>退出登录</button>
    </div>
  );
};

关键注意事项

  • 永远不要在服务端渲染的组件顶层(比如函数组件的直接代码块)访问localStorage,必须限制在客户端执行环境中。
  • 存储敏感token时,Cookie的HttpOnly属性比localStorage更安全,能有效防范XSS攻击。
  • 使用JWT时,要做好token过期检测和刷新逻辑,避免用户频繁登录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:10:19