Next.js14+Next-Auth v5中Idle-Session-Timeout报window未定义如何解决?
解决方案
因为idle-session-timeout依赖浏览器的window对象,而你的layout.tsx是服务器组件(需要调用await auth()),不能直接在里面运行客户端代码,解决思路是把超时逻辑拆分到独立的客户端组件中,具体步骤如下:
1. 创建客户端组件封装超时逻辑
新建一个比如components/IdleSessionTimeout.tsx文件,标记为客户端组件(顶部加'use client'),在里面引入idle-session-timeout并实现逻辑:
'use client'; import { useEffect } from 'react'; import idleSessionTimeout from 'idle-session-timeout'; import { signOut } from 'next-auth/react'; export default function IdleSessionTimeout() { useEffect(() => { const timeoutInstance = idleSessionTimeout({ timeout: 3600000, // 示例:1小时超时 onTimeout: () => { // 超时后执行退出登录 signOut({ callbackUrl: '/' }); }, // 其他配置项按需添加 }); // 组件卸载时清理实例 return () => timeoutInstance.destroy(); }, []); return null; // 该组件无需渲染可见内容 }
2. 在layout.tsx中引入该客户端组件
你的layout.tsx作为服务器组件,可直接导入并渲染这个客户端组件,同时保留await auth()的逻辑:
import { auth } from '@/auth'; // 你的next-auth配置路径 import IdleSessionTimeout from '@/components/IdleSessionTimeout'; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const session = await auth(); return ( <html lang="zh-CN"> <body> {/* 保留原有布局内容 */} {session && <IdleSessionTimeout />} {/* 仅用户登录时加载超时组件 */} {children} </body> </html> ); }
3. 额外优化(可选)
如果需要根据服务器端获取的session信息配置超时参数(比如不同用户组对应不同超时时间),可将session中的数据作为props传递给客户端组件:
// 在layout中传递参数 {session && <IdleSessionTimeout timeout={session.user.customTimeout || 3600000} />} // 在IdleSessionTimeout组件中接收并使用 export default function IdleSessionTimeout({ timeout }: { timeout: number }) { useEffect(() => { const timeoutInstance = idleSessionTimeout({ timeout, // ...其他配置 }); return () => timeoutInstance.destroy(); }, [timeout]); return null; }
内容的提问来源于stack exchange,提问作者charan vendra
相关产品推荐
相关产品推荐

