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

Next.js + Auth.js登出Bug:特定页面UI状态无法更新求助

问题排查:Next.js Auth.js 登出后UI卡在Pending状态

核心问题分析

在受保护路由 /account/today 点击登出按钮时,服务器返回303重定向,但useFormStatus的pending状态无法重置,导致UI一直处于加载状态;而首页登出流程正常。结合代码来看,问题大概率出在中间件对登出请求的拦截或客户端钩子的使用规范上。


排查方案与修复

1. 中间件拦截了登出请求

你的中间件配置中,isApiAuthRoutes会匹配所有以apiAuthPrefix(推测为/api/auth)开头的路径,包括Auth.js的登出接口/api/auth/signout。当用户在已登录状态下访问这个接口时,中间件会强制重定向到/account/today,打断了正常的登出流程,导致客户端无法收到登出完成的信号,pending状态一直保持。

修复代码:修改middleware.ts中的isApiAuthRoutes逻辑,允许已登录用户访问登出接口:

if (isApiAuthRoutes) {
  // 仅在非登出路径下,对已登录用户重定向
  if (isLoggedIn && !nextUrl.pathname.endsWith('/signout')) {
    return Response.redirect(new URL('/account/today', nextUrl));
  }
  return undefined;
}

2. 未正确使用useFormStatus客户端钩子

useFormStatus是React 18+的客户端专属钩子,必须满足两个条件:

  • 组件需添加'use client'指令
  • 组件必须是<form>的直接后代(你的代码结构符合,但需确认客户端指令)

修复代码:在SidebarLogout组件顶部添加客户端指令:

'use client';
import { useFormStatus } from 'react-dom';
// 其他导入和组件代码...

3. 验证Server Action是否正常执行

可以在登出的Server Action中添加日志,确认是否被中间件拦截:

export const logOut = async () => {
  console.log('登出Server Action执行中');
  await signOut({ redirectTo: "/" });
};
  • 如果在/account/today点击登出时控制台没有输出该日志,说明中间件拦截了请求,优先处理方案1;
  • 如果有日志输出,说明登出流程已执行,但客户端未处理重定向,可尝试在Server Action中手动返回重定向(兜底处理):
    export const logOut = async () => {
      await signOut({ redirectTo: "/" });
      // 手动返回重定向,确保客户端收到信号
      return Response.redirect(new URL("/", process.env.NEXT_PUBLIC_APP_URL));
    };
    

额外验证点

  • 确认publicRoutes数组包含"/",确保登出后重定向到的首页是公共路由,不会被中间件再次拦截;
  • 检查浏览器网络请求,查看登出请求的响应是否正确:正常情况下应该是303重定向到"/",而不是被中间件重定向回/account/today。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:00:02