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

Next.js中如何在getStaticProps中获取AuthContext存储的用户accessToken?

Next.js中如何在getStaticProps中获取AuthContext存储的用户accessToken?

首先得明确一个核心问题:getStaticProps根本没法直接访问React的Context或者hooks,这是Next.js的设计逻辑决定的——getStaticProps是在**构建阶段(或者ISR的后台刷新阶段)**运行的,它完全脱离React组件树,既不在客户端浏览器环境,也不参与组件的渲染流程,所以你调用useAuth钩子才会触发那个错误。

那怎么解决你的需求呢?给你几个实用的方案,你可以根据自己的业务场景选择:

方案一:改用getServerSideProps获取用户token

如果你的页面需要针对每个登录用户展示个性化数据,且能接受服务器端渲染(SSR)的性能损耗,那把getStaticProps换成getServerSideProps是最直接的办法。

getServerSideProps会在每次用户请求页面时在服务器端运行,虽然它也不能直接用React hooks,但你可以从请求的Cookie(或者请求头)里拿到用户的accessToken——毕竟用户登录后,token一般会存在Cookie或者localStorage里,而Cookie会自动随请求发送到服务器。

举个具体的例子(假设你的token存在名为accessToken的Cookie里):

import cookie from 'cookie';
import axios from 'axios';

export async function getServerSideProps(context) {
  // 解析请求头里的Cookie
  const cookies = cookie.parse(context.req.headers.cookie || '');
  const accessToken = cookies.accessToken;

  // 如果没有token,直接重定向到登录页
  if (!accessToken) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  try {
    // 带着token请求API
    const result = await axios.get("http://127.0.0.1:5000/track/landing-tracks-for-admin", {
      headers: {
        Authorization: `Bearer ${accessToken}`
      }
    });

    return {
      props: {
        tracks: result.data,
      },
    };
  } catch (error) {
    // 处理token过期或无效的情况,比如重定向登录
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }
}

方案二:在客户端组件内获取数据

如果你的页面可以接受“先展示静态骨架,再在客户端加载用户专属数据”的体验,那可以保留getStaticProps(用来生成静态页面的基础结构),然后在组件内部借助AuthContext拿到token,再请求API。

推荐用SWR或者React Query这类数据获取库,它们能帮你处理缓存、重新请求等逻辑,比原生useEffect更优雅:

import useAuth from "../../hooks/useAuth";
import useSWR from 'swr';

// 封装带token的请求函数
const fetcher = (url, token) => 
  axios.get(url, {
    headers: { Authorization: `Bearer ${token}` }
  }).then(res => res.data);

export default function AdminTracksPage() {
  const { auth } = useAuth();
  // 只有当token存在时才发起请求
  const { data: tracks, error } = useSWR(
    auth.accessToken ? ["http://127.0.0.1:5000/track/landing-tracks-for-admin", auth.accessToken] : null,
    fetcher
  );

  if (error) return <div>加载曲目失败,请稍后重试</div>;
  if (!tracks) return <div>加载中...</div>;

  // 渲染你的曲目列表
  return (
    <div className="track-list">
      {tracks.map(track => (
        <div key={track.id}>{track.name}</div>
      ))}
    </div>
  );
}

// 用getStaticProps生成静态页面的基础结构
export async function getStaticProps() {
  return {
    props: {}, // 不需要传递动态数据,因为数据在客户端获取
    revalidate: 5,
  };
}

方案三:特殊场景:静态生成+个性化数据(不推荐)

如果你的业务必须用getStaticProps(比如需要完全静态化且CDN缓存),但又要展示用户个性化数据,这种场景其实非常矛盾——静态生成的页面是通用的,没法针对每个用户定制。

唯一的折中方式是把用户ID作为路由参数(比如/admin/tracks/[userId]),然后用getStaticPaths预生成所有可能的用户页面,但这显然不现实(用户数量多的话根本生成不过来),而且token的安全性也没法保证,所以这个方案只适合极少数特殊场景,一般不推荐。


总结一下:如果需要服务器端实时获取用户数据,选方案一;如果可以接受客户端加载数据,选方案二;方案三尽量不要用。

备注:内容来源于stack exchange,提问作者Ahmed Sbai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 08:24:09