03-状态管理与路由——07-路由守卫与权限控制
路由守卫与权限控制一、路由守卫实现1.1 基础守卫组件import { Navigate } from react-router-dom; function PrivateRoute({ children }) { const isLoggedIn localStorage.getItem(token); if (!isLoggedIn) { return Navigate to/login replace /; } return children; } // 使用 Route path/dashboard element{ PrivateRoute Dashboard / /PrivateRoute } /1.2 基于角色的守卫function RoleRoute({ children, requiredRole }) { const user useSelector(state state.user); if (!user) { return Navigate to/login replace /; } if (user.role ! requiredRole) { return Navigate to/unauthorized replace /; } return children; } // 使用 Route path/admin element{ RoleRoute requiredRoleadmin AdminPanel / /RoleRoute } / Route path/editor element{ RoleRoute requiredRoleeditor EditorPanel / /RoleRoute } /二、高级守卫模式2.1 使用 useAuth Hook// hooks/useAuth.js function useAuth() { const [user, setUser] useState(null); const [loading, setLoading] useState(true); useEffect(() { checkAuth() .then(user { setUser(user); setLoading(false); }) .catch(() setLoading(false)); }, []); return { user, loading }; } // 守卫组件 function PrivateRoute({ children }) { const { user, loading } useAuth(); if (loading) return div验证中.../div; if (!user) return Navigate to/login /; return children; }2.2 路由配置式守卫const routes [ { path: /, element: Layout /, children: [ { index: true, element: Home / }, { path: dashboard, element: Dashboard /, requiresAuth: true }, { path: admin, element: Admin /, requiresAuth: true, requiredRole: admin } ] } ]; // 路由包装器 function AppRoutes() { return ( Routes {routes.map(route ( Route key{route.path} path{route.path} element{route.element} {route.children?.map(child { let element child.element; if (child.requiresAuth) { element ( PrivateRoute requiredRole{child.requiredRole} {child.element} /PrivateRoute ); } return Route key{child.path} path{child.path} element{element} /; })} /Route ))} /Routes ); }三、登录后重定向function LoginPage() { const navigate useNavigate(); const location useLocation(); // 获取来源路径 const from location.state?.from?.pathname || /; const handleLogin async () { await login(); navigate(from, { replace: true }); }; return ( div button onClick{handleLogin}登录/button p登录后跳转到: {from}/p /div ); } // 守卫中传递来源 function PrivateRoute({ children }) { const isLoggedIn checkAuth(); const location useLocation(); if (!isLoggedIn) { return Navigate to/login state{{ from: location }} replace /; } return children; }四、权限控制 Hook// hooks/usePermission.js function usePermission() { const user useSelector(state state.user); const hasPermission (permission) { return user?.permissions?.includes(permission) || user?.role admin; }; const hasRole (role) { return user?.role role; }; const hasAnyRole (roles) { return roles.some(role user?.role role); }; return { hasPermission, hasRole, hasAnyRole, user }; } // 组件内使用 function AdminButton() { const { hasPermission } usePermission(); if (!hasPermission(delete_user)) return null; return button classNamedanger删除用户/button; } function UserMenu() { const { hasAnyRole } usePermission(); if (hasAnyRole([admin, editor])) { return AdminMenu /; } return UserMenu /; }五、权限指令组件// 权限控制组件 function Can({ permission, role, children, fallback null }) { const { hasPermission, hasRole } usePermission(); let hasAccess false; if (permission) { hasAccess hasPermission(permission); } if (role) { hasAccess hasRole(role); } return hasAccess ? children : fallback; } // 使用 function Dashboard() { return ( div Can permissionview_dashboard DashboardContent / /Can Can permissiondelete_user fallback{button disabled删除/button} DeleteButton / /Can Can roleadmin AdminPanel / /Can /div ); }