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

Next-Auth v5 SSR页面API返回401时自动登出问题求助

Next-Auth v5 SSR页面401自动登出解决方案

针对你在SSR页面遇到的401无法调用signOut的问题,给你几个可行的解决思路:

方法1:服务器端清除会话并重定向

Next-Auth v5的服务器端auth()函数自带登出能力,你可以直接在SSR页面中调用它的signOut方法清除会话,再重定向到登录页完成流程。修改代码如下:

import auth from "@/lib/auth";
import { redirect } from "next/navigation";

export default async function Page() {
  const session = await auth();
  const token = session?.accessToken;

  const data = await getData({
    token: token || "",
  });

  if (data.status === 401) {
    // 服务器端清除会话
    await auth().signOut();
    // 重定向到登录页
    redirect("/login");
  }

  return (
    <>{data.result}</>
  );
}

auth().signOut()会自动清除会话cookie,重定向后用户就处于未登录状态。

方法2:将401处理逻辑移到客户端组件

如果服务器端重定向不符合需求,可以把数据请求和401检测放到客户端组件中,使用Next-Auth的客户端钩子处理:

先创建客户端组件DataComponent.jsx:

"use client";

import { useSession, signOut } from "next-auth/react";
import { useEffect, useState } from "react";

export default function DataComponent() {
  const { data: session } = useSession();
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      if (!session?.accessToken) return;
      const res = await getData({ token: session.accessToken });
      if (res.status === 401) {
        await signOut();
        setError(res.error);
        return;
      }
      setData(res.result);
    };

    fetchData();
  }, [session]);

  if (error) return <p>Error: {error}</p>;
  if (!data) return <p>Loading...</p>;

  return <>{data}</>;
}

然后在SSR页面中引入该组件,同时保留服务器端会话验证:

import auth from "@/lib/auth";
import { redirect } from "next/navigation";
import DataComponent from "./DataComponent";

export default async function Page() {
  const session = await auth();
  if (!session) {
    redirect("/login");
  }

  return <DataComponent />;
}

这种方式既保留了SSR的会话校验能力,又能在客户端触发signOut。

方法3:服务器端标记状态,客户端全局处理

你可以在SSR页面检测到401时设置自定义响应头,然后在根布局的客户端逻辑中监听该头信息,触发登出:

  1. SSR页面中设置响应头:
import auth from "@/lib/auth";
import { headers } from "next/headers";

export default async function Page() {
  const session = await auth();
  const token = session?.accessToken;
  const headersList = headers();
  const responseHeaders = new Headers(headersList);

  const data = await getData({
    token: token || "",
  });

  if (data.status === 401) {
    responseHeaders.set("X-Auth-Error", "401");
    await auth().signOut();
  }

  return (
    <>
      {data.status === 401 ? <p>Error: {data.error}</p> : <>{data.result}</>}
    </>
  );
}
  1. 在根布局(客户端)中监听并处理:
"use client";

import { signOut } from "next-auth/react";
import { useEffect } from "react";

export default function RootLayout({ children }) {
  useEffect(() => {
    fetch(window.location.href, { method: "HEAD" })
      .then(res => {
        if (res.headers.get("X-Auth-Error") === "401") {
          signOut();
        }
      });
  }, []);

  return (
    <html lang="zh-CN">
      <body>{children}</body>
    </html>
  );
}

这个方案适合需要全局统一处理401登出的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:43:18