JS怎样实现前端路由拦截 5种路由拦截方案保障前端页面权限

JS怎样实现前端路由拦截 5种路由拦截方案保障前端页面权限
最新回答
詯啲笶♀昻贵

2026-04-22 23:49:18

JS 实现前端路由拦截的核心是在路由跳转前后进行权限判断,以下提供 5 种常见方案保障前端页面权限:

1. 全局路由守卫(Vue Router / React Router)

通过集中式管理权限,在路由跳转前统一校验用户权限。

  • Vue Router 示例:

    router.beforeEach((to, from, next) => { const requiresAuth = to.matched.some(record => record.meta.requiresAuth); const isLoggedIn = localStorage.getItem('token'); if (requiresAuth && !isLoggedIn) { next('/login'); // 重定向到登录页 } else { next(); // 允许跳转 }});
  • React Router 示例(使用 useNavigate 钩子):

    import { useNavigate, useLocation } from 'react-router-dom';import { useEffect } from 'react';function AuthGuard({ children, requiredRoles }) { const navigate = useNavigate(); const location = useLocation(); const isLoggedIn = localStorage.getItem('token'); const userRole = localStorage.getItem('role'); useEffect(() => { if (!isLoggedIn) { navigate('/login', { replace: true, state: { from: location } }); } else if (requiredRoles && !requiredRoles.includes(userRole)) { navigate('/unauthorized'); } }, [isLoggedIn, navigate, location, requiredRoles, userRole]); return children;}
2. 组件级别权限控制(Higher-Order Components - HOC)

通过高阶组件包裹需要权限控制的组件,实现更灵活的权限管理。

  • React 示例:function withAuth(WrappedComponent, requiredRole) { return function(props) { const isLoggedIn = localStorage.getItem('token'); const userRole = localStorage.getItem('role'); if (!isLoggedIn || (requiredRole && userRole !== requiredRole)) { return <div>您没有权限访问此页面</div>; } return <WrappedComponent {...props} />; };}// 使用const AdminDashboard = withAuth(Dashboard, 'admin'); // 只有 admin 角色才能访问
3. 服务端渲染(SSR)时的权限控制

在服务端进行权限判断,提高安全性但增加实现复杂度。

  • Next.js 示例:export async function getServerSideProps(context) { const { req, res } = context; const token = req.cookies.token; if (!token) { return { redirect: { destination: '/login', permanent: false, }, }; } try { const user = await verifyToken(token); // 校验 token return { props: { user }, }; } catch (error) { return { redirect: { destination: '/login', permanent: false, }, }; }}function MyPage({ user }) { // ...}
4. 路由配置中的 Meta 字段

在路由配置中添加 meta 字段存储权限信息,结合全局守卫进行校验。

  • Vue Router 示例:const routes = [ { path: '/admin', component: AdminDashboard, meta: { requiresAuth: true, role: 'admin' }, },];router.beforeEach((to, from, next) => { if (to.meta.requiresAuth) { const isLoggedIn = localStorage.getItem('token'); const userRole = localStorage.getItem('role'); if (!isLoggedIn) { next('/login'); } else if (to.meta.role && userRole !== to.meta.role) { next('/unauthorized'); } else { next(); } } else { next(); }});
5. 动态路由

根据用户权限动态生成路由表,实现精细化控制。

  • 实现逻辑:

    用户登录后,从服务器获取权限列表。

    根据权限列表动态生成路由表。

    示例代码(Vue Router):// 假设从服务器获取的权限列表const permissions = ['admin', 'editor'];// 动态生成路由const dynamicRoutes = permissions.includes('admin') ? [ { path: '/admin', component: AdminDashboard, meta: { requiresAuth: true, role: 'admin' }, }, ] : [];// 添加到路由表router.addRoutes(dynamicRoutes);

最佳实践与注意事项
  • SPA 路由拦截:推荐结合全局路由守卫和组件级控制,平衡集中管理与灵活性。
  • 异步权限验证:使用 async/await 或 Promise 处理服务器端权限校验。router.beforeEach(async (to, from, next) => { if (to.meta.requiresAuth) { const isLoggedIn = localStorage.getItem('token'); if (!isLoggedIn) { next('/login'); return; } try { const user = await getUserInfo(); // 异步获取用户信息 store.commit('setUser', user); next(); } catch (error) { localStorage.removeItem('token'); next('/login'); } } else { next(); }});
  • 避免死循环:在路由守卫中判断当前路径,防止登录页重定向死循环。router.beforeEach((to, from, next) => { if (to.path === '/login') { next(); // 直接放行登录页 return; } if (to.meta.requiresAuth) { const isLoggedIn = localStorage.getItem('token'); if (!isLoggedIn) { next('/login'); } else { next(); } } else { next(); }});

通过以上方案,可以灵活实现前端路由拦截,保障页面权限安全。