私域操盘手 - 增加路由守卫,拦截所有未登录的页面及页面请求

This commit is contained in:
柳清爽
2025-05-16 10:11:08 +08:00
parent 47b32684b9
commit 4934460997
6 changed files with 63 additions and 5 deletions

View File

@@ -0,0 +1,27 @@
"use client"
import { useEffect } from "react"
import { useRouter, usePathname } from "next/navigation"
export function AuthCheck({ children }: { children: React.ReactNode }) {
const router = useRouter()
const pathname = usePathname()
useEffect(() => {
// 排除不需要登录的页面
const publicPaths = ['/login', '/register', '/forgot-password']
if (publicPaths.includes(pathname)) {
return
}
const token = localStorage.getItem('token')
if (!token) {
// 如果没有token重定向到登录页面并携带当前页面URL作为回调
const currentPath = window.location.pathname + window.location.search
router.push(`/login?redirect=${encodeURIComponent(currentPath)}`)
return
}
}, [router, pathname])
return <>{children}</>
}

View File

@@ -0,0 +1,14 @@
const ToastViewport = React.forwardRef<
React.ElementRef<typeof ToastPrimitives.Viewport>,
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
>(({ className, ...props }, ref) => (
<ToastPrimitives.Viewport
ref={ref}
className={cn(
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
className
)}
{...props}
/>
))
ToastViewport.displayName = ToastPrimitives.Viewport.displayName

View File

@@ -95,6 +95,17 @@ export default function DeviceDetailPage() {
})
const [tabChangeLoading, setTabChangeLoading] = useState(false)
// 添加登录检查
useEffect(() => {
const token = localStorage.getItem('token')
if (!token) {
// 如果没有token重定向到登录页面并携带当前页面URL作为回调
const currentPath = window.location.pathname + window.location.search
router.push(`/login?redirect=${encodeURIComponent(currentPath)}`)
return
}
}, [router])
useEffect(() => {
if (!params.id) return

View File

@@ -5,6 +5,8 @@ import type React from "react"
import ErrorBoundary from "./components/ErrorBoundary"
import { AuthProvider } from "@/app/components/AuthProvider"
import LayoutWrapper from "./components/LayoutWrapper"
import { AuthCheck } from "@/app/components/auth-check"
import { Toaster } from "sonner"
export const metadata: Metadata = {
title: "存客宝",
@@ -21,10 +23,13 @@ export default function RootLayout({
<html lang="zh-CN" suppressHydrationWarning>
<body className="bg-gray-100">
<AuthProvider>
<ErrorBoundary>
<LayoutWrapper>{children}</LayoutWrapper>
</ErrorBoundary>
<AuthCheck>
<ErrorBoundary>
<LayoutWrapper>{children}</LayoutWrapper>
</ErrorBoundary>
</AuthCheck>
</AuthProvider>
<Toaster />
</body>
</html>
)