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

如何让SWR等待Next Auth会话加载完成后再发起请求?

解决Next Auth会话同步延迟导致SWR提前请求的问题

核心思路是等待Next Auth完成会话状态同步后,再触发SWR的数据请求,以下是几种可行的实现方案:

方案一:利用useSession状态控制SWR请求时机

useSession钩子会返回会话的status状态(loading/authenticated/unauthenticated),我们可以通过这个状态配合SWR的enabled选项,控制请求仅在会话加载完成后发起:

import { useSession } from "next-auth/react";
import useSWR from "swr";

// 带身份验证的请求函数
const authFetcher = async (url, token) => {
  const res = await fetch(url, {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });
  
  if (!res.ok) throw new Error("数据请求失败");
  return res.json();
};

function UserProfile() {
  const { data: session, status } = useSession();

  // 仅当会话已认证时,才传入请求key并启用SWR
  const { data: userData, error } = useSWR(
    status === "authenticated" ? ["/api/user/profile", session.user.accessToken] : null,
    authFetcher,
    { enabled: status === "authenticated" }
  );

  // 会话加载中时显示占位
  if (status === "loading") return <div>加载中...</div>;
  // 请求失败处理
  if (error) return <div>获取用户数据失败</div>;
  // 数据未就绪时返回空
  if (!userData) return null;

  return <div>用户名:{userData.name}</div>;
}

export default UserProfile;

方案二:封装自定义Hook统一处理逻辑

如果多个组件都需要类似的逻辑,可以封装一个自定义Hook,整合useSession和useSWR的逻辑,减少重复代码:

import { useSession } from "next-auth/react";
import useSWR from "swr";

export function useAuthSWR(key, fetcher, options = {}) {
  const { data: session, status } = useSession();

  // 合并SWR配置,强制会话认证后才启用请求
  const swrConfig = {
    ...options,
    enabled: (options.enabled ?? true) && status === "authenticated"
  };

  // 给fetcher注入会话信息
  const authFetcher = session ? (...args) => fetcher(...args, session) : null;

  return useSWR(
    status === "authenticated" ? key : null,
    authFetcher,
    swrConfig
  );
}

// 使用示例
function Dashboard() {
  const { data: dashboardData, error } = useAuthSWR(
    "/api/dashboard",
    (url, session) => fetch(url, {
      headers: { Authorization: `Bearer ${session.user.accessToken}` }
    }).then(res => res.json())
  );

  const { status } = useSession();
  if (status === "loading") return <div>初始化中...</div>;
  if (error) return <div>加载仪表盘失败</div>;

  return <div>今日访问量:{dashboardData.views}</div>;
}

方案三:在Fetcher中主动校验会话(辅助方案)

如果需要在请求层面做兜底校验,可以在fetcher中主动获取会话,若会话未就绪则抛出错误,但仍建议配合enabled选项使用,避免不必要的请求:

import { getSession } from "next-auth/react";
import useSWR from "swr";

const safeFetcher = async (url) => {
  const session = await getSession();
  if (!session) throw new Error("会话未就绪");

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${session.user.accessToken}` }
  });
  return res.json();
};

function Orders() {
  const { status } = useSession();
  const { data: orders, error } = useSWR(
    "/api/orders",
    safeFetcher,
    { enabled: status !== "loading" }
  );

  if (status === "loading") return <div>加载中...</div>;
  if (error) return <div>获取订单失败:{error.message}</div>;

  return <ul>{orders.map(order => <li key={order.id}>订单{order.id}</li>)}</ul>;
}

所有方案的核心都是通过Next Auth的会话状态判断,确保SWR仅在会话就绪后发起请求,避免因会话未同步导致的无效请求或权限错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:01:23