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

NextAuth+AuthRoute环境下SWR请求先于Token设置致401问题排查

问题根源分析

1. SWR请求发起时机早于Token设置

AuthRoute中通过useEffect设置Axios默认Token,但useEffect是组件渲染完成后才执行的。而子组件(QuoteList)中的SWR请求会在组件挂载时立刻触发,此时Axios的Authorization头还未被设置,导致首次请求无Token返回401。

2. Fetcher函数未返回Promise

useFetch.ts中的fetcher函数没有返回api.get()的Promise,导致SWR无法正确识别请求状态,会自动重试请求。此时Token已经通过useEffect设置完成,所以后续重试请求能成功,但首次请求必然401。

3. 潜在的Session字段拼写错误

QuoteList中写了session?.data?.access_token,但NextAuth配置中session的Token字段是accessToken(驼峰),虽然useFetch中用了正确的session.data.accessToken,但这个拼写错误可能导致其他逻辑异常。


解决方案

1. 修正Fetcher函数,确保返回Promise

修改useFetch.ts中的fetcher,返回完整的Promise链:

const fetcher = (url) => {
  return api
    .get(url, {
      withCredentials: true,
    })
    .then((res) => {
      console.log(res.data);
      return res.data;
    });
};

2. 提前Token设置时机,避免依赖useEffect

在AuthRoute中,确认Session存在后立刻设置Token,而不是等到useEffect执行。因为AuthRoute已经通过status !== 'loading' && userExists判断后才渲染子组件,此时可以直接同步设置Token:

const AuthRoute = ({ children }) => {
  const { data: session, status } = useSession({ required: true });
  const userExists = !!session?.user;
  const router = useRouter();

  useEffect(() => {
    if (status !== 'loading' && !userExists) {
      router.push('/auth/login');
    }
  }, [status, userExists, router]);

  // 同步设置Token,无需等待useEffect
  if (status === 'loading' || !userExists) {
    return <div>Waiting</div>;
  }

  setToken(session.accessToken);
  return children;
};

这样子组件渲染时,Axios的默认头已经设置完成,SWR首次请求就能携带Token。

3. 优化SWR请求触发条件(可选)

在useFetch中,确保只有当Session和Token都明确存在时才生成SWR的key,避免无效请求:

export function useFetchQuotes(
  session,
  filters,
  paginationModel = { page: 0, pageSize: 10 },
) {
  console.log('useFetchQuotes', session);

  // 确保session.data和accessToken都存在才发起请求
  const swrKey = session?.data?.accessToken 
    ? `url goes here` // 替换为实际请求URL
    : null;

  const { data, error, isLoading } = useSWR(swrKey, fetcher);

  let count = 5;

  return { data, error, isLoading, count };
}

4. 修正Session字段拼写错误

将QuoteList中的session?.data?.access_token改为session?.data?.accessToken,保持和NextAuth配置一致:

const headers = { Authorization: `Bearer ${session?.data?.accessToken}` };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 02:52:51