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

Next-auth登出后自动跳回仪表盘的问题求助

问题描述

我在NextJS中采用基于凭证的认证流程,设有仪表盘页面,同时创建了自定义AccessDenied组件,用于处理未登录用户访问仪表盘路由的情况,因此在获取数据的getServerSideProps中未设置重定向。我的登出处理代码如下:

onClick={() => {
  signOut();
  router.push("/");
}}

但执行登出后,我先进入首页,不久后却被重定向到仪表盘页面,不清楚原因。以下是仪表盘页面代码:

const DashboardPage = ({
  sessionData,
}: InferGetServerSidePropsType<typeof getServerSideProps>) => {
  const [renderedInfo, setRenderedInfo] = useState<RenderedInfo>();
  const matches = useMediaQuery("(max-width: 768px)");

  useEffect(() => {
    if (!matches) setRenderedInfo("UserDetails");
  }, [matches]);

  if (!sessionData) {
    return <AccessDenied />;
  }

  const { address, userEmail, avatar } = sessionData;
  const menuPanelVisible = !matches || (matches && !renderedInfo);
  const userDisplayName = address?.length ? address[0] : userEmail;
  return (
    <div className="flex-1 px-4 flex w-full justify-center">
      {menuPanelVisible && (
        <MenuPanel>
          <UserAvatar avatar={avatar} displayName={userDisplayName} />
          <DashboardNavigation setRenderedInfo={setRenderedInfo} />
        </MenuPanel>
      )}
      <InformationPanel
        renderedInfo={renderedInfo}
        setRenderedInfo={setRenderedInfo}
        address={address}
      />
    </div>
  );
};

export default DashboardPage;

interface GetServerSidePropsType {
  sessionData?: {
    address: string[] | undefined;
    avatar:
      | {
          url: string;
          width?: number | null | undefined;
          height?: number | null | undefined;
        }
      | null
      | undefined;
    userEmail: string;
  } | null;
}

export const getServerSideProps: GetServerSideProps<
  GetServerSidePropsType
> = async (context) => {
  const session = await unstable_getServerSession(
    context.req,
    context.res,
    authOptions
  );

  console.log({ email: session?.user.email });

  if (!session?.user.email) {
    return {
      props: {
        session: null,
      },
    };
  }

  const { data } = await personAuthApolloClient.query<
    GetPersonDetailsByEmailQuery,
    GetPersonDetailsByEmailQueryVariables
  >({
    query: GetPersonDetailsByEmailDocument,
    variables: {
      email: session.user.email,
    },
  });

  const address = data.person?.address;
  const avatar = data.person?.avatar;
  const sessionData = { address, avatar, userEmail: session.user.email };

  return {
    props: { sessionData },
  };
};

请问我该如何操作才能在登出重定向后停留在首页?

解决方案

1. 修正登出逻辑:等待signOut完成并禁用自动重定向

signOut 是异步函数,且默认会触发自动重定向,和你手动调用的 router.push 冲突,导致跳转逻辑混乱。修改登出代码为:

onClick={async () => {
  // 禁用signOut的自动重定向,等待session清除完成
  await signOut({ redirect: false });
  // 再手动跳转到首页
  router.push("/");
}}

2. 修复getServerSideProps的props返回错误

你的仪表盘组件接收的是 sessionData,但在未登录时,getServerSideProps返回的是 session: null,导致组件中 sessionData 为 undefined(虽然当前逻辑能显示AccessDenied,但可能引发状态判断异常)。修正这段代码:

if (!session?.user.email) {
  return {
    props: {
      sessionData: null, // 改为sessionData,和组件props对应
    },
  };
}

3. 客户端监听session状态(可选)

为了避免客户端session状态和服务端不同步导致的异常跳转,可以在仪表盘页面添加session监听,当session失效时自动跳转首页:

import { useSession } from "next-auth/react";
import { useRouter } from "next/router";

// 在DashboardPage组件内添加:
const { data: session } = useSession();
const router = useRouter();

useEffect(() => {
  if (!session) {
    router.push("/");
  }
}, [session, router]);

这样就能确保登出后稳定停留在首页,不会出现自动跳回仪表盘的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:48:33