多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

mern-admin 路由权限设计:PrivateRoute 与 PublicRoute 守卫原理

mern-admin 路由权限设计:PrivateRoute 与 PublicRoute 守卫原理 mern-admin 路由权限设计PrivateRoute 与 PublicRoute 守卫原理【免费下载链接】mern-adminMERN Antd Admin MongoDB Nodejs React Node Js Rest Api CRUD Auth项目地址: https://gitcode.com/gh_mirrors/me/mern-adminmern-admin 是一个基于 MERN 技术栈MongoDB、Express、React、Node.js并搭配 Ant DesignAntd的开源后台管理系统模板。在本文中我们将深入剖析 mern-admin 的路由权限设计重点讲解 PrivateRoute 与 PublicRoute 两个路由守卫的核心原理、Token 校验机制以及登录拦截的完整闭环。无论你是刚入门 React 路由权限控制的新手还是想快速改造后台管理系统的开发者这篇路由守卫指南都能帮你少走弯路。为什么后台管理系统需要路由权限守卫后台管理系统最大的安全风险之一就是未登录用户直接通过 URL 访问受保护页面。比如直接输入/admin或/customer如果没有路由守卫页面就会把内部数据赤裸裸地暴露出来。mern-admin 用一套双守卫方案解决了这个问题规则非常清晰场景访问目标守卫裁决最终去向未登录用户受保护页如/adminPrivateRoute 拦截重定向到/login已登录用户登录页/loginPublicRoute 拦截重定向回首页/已登录用户受保护页PrivateRoute 放行正常渲染页面 ✅这套设计的巧妙之处在于登录页和业务页共用一套鉴权状态只是判断逻辑正好相反代码量极小却覆盖了所有越权场景。PrivateRoute 守卫原理未登录就重定向到 /loginPrivateRoute 是 mern-admin 中最核心的路由守卫源码位于frontend/src/router/PrivateRoute.jsx。它的核心逻辑只有一句话有 Token 就渲染页面没有 Token 就重定向到登录页。Route {...rest} render{(props) authService.token.get() ? ( Component {...props} / ) : ( Redirect to/login / ) } /可以看到守卫的判决依据是authService.token.get()的返回值。Token 存在时页面组件被正常渲染并且包裹在 framer-motion 的动画容器中实现淡入上移的转场效果Token 为空时立即触发Redirect to/login /把用户踢回登录页。用户访问 /admin │ ▼ token.get() 有值 ├── 是 ──► 渲染 Admin 页面带转场动画 └── 否 ──► Redirect to /login强制登录PublicRoute 守卫原理已登录用户不再看登录页PublicRoute 位于frontend/src/router/PublicRoute.jsx它的职责和 PrivateRoute 正好互补已登录用户访问登录页时直接送回首页避免出现明明已登录还要再看一遍登录表单的尴尬体验。Route {...rest} render{(props) authService.token.get() ? ( Redirect to/ / ) : ( Component {...props} / ) } /这个设计还有一个隐藏好处当你手动在地址栏输入/login时如果会话仍有效系统会立刻把你送回主界面从入口处就杜绝了重复登录。守卫的判断依据Token 到底存在哪里理解了守卫逻辑后最关键的问题来了authService.token.get()读的到底是什么答案藏在frontend/src/auth/cookie.js中——它虽然叫 cookie但实际使用的是localStorage存储键名是x-auth-token定义于frontend/src/config/serverApiConfig.js。frontend/src/auth/auth.service.js封装了token.get()、token.set()、token.remove()三个方法分别对应读取、写入、清除 Token登录成功后调用token.set(response.data.result.token)把后端签发的 Token 持久化到本地退出登录时调用token.remove()清除 Token同时清空整个 localStorage。为什么要用 localStorage 而不是内存因为刷新页面时内存状态会全部丢失而 localStorage 的持久化能力让刷新后依然保持登录状态。这也解释了为什么 mern-admin 刷新后不会掉线。路由如何被组织AppRouter 与 AuthRouter 的切换逻辑有了守卫组件还需要把它们挂载到路由树上。mern-admin 把路由分成两棵子树由frontend/src/router/index.jsx根据 Redux 中的isLoggedIn状态决定渲染哪一棵AuthRouterfrontend/src/router/AuthRouter.jsx未登录时的路由集合只包含登录页和 404 页且所有页面都用 PublicRoute 包裹AppRouterfrontend/src/router/AppRouter.jsx已登录时的路由集合包含 Dashboard、Customer、Lead、Product、Admin、Logout 等全部业务页全部用 PrivateRoute 包裹同时挂载侧边导航 Navigation。if (isLoggedIn false) return AuthRouter /; // 只显示登录页 else return AppRouter /; // 显示完整后台 导航值得一提的是AppRouter 中的所有页面都使用了React.lazy 懒加载 Suspense PageLoader的组合配合 AnimatePresence 实现路由切换动画。这意味着业务页面按需加载首屏只加载登录页性能更优具体实现见frontend/src/router/AppRouter.jsx。登录与退出守卫状态的完整闭环光有路由守卫还不够登录、退出的状态流转才是完整闭环。登录流程贯穿了前端 Redux 与后端接口链路如下用户在登录页提交账号密码触发frontend/src/redux/auth/actions.js中的loginaction调用authService.login()请求后端/login接口成功后把 Token 写入 localStorage同时把{ current, loading, isLoggedIn: true }持久化到 localStorage 的auth键frontend/src/redux/storePersist.jsdispatchLOGIN_SUCCESS更新 Redux 状态Router组件监听到isLoggedIn变为 true自动切换到 AppRouter最后history.push(/)跳转首页完成登录闭环。退出登录则是反向操作logoutaction 先清除 Token 和持久化数据再 dispatchLOGOUT_SUCCESSRedux 状态回到初始值路由自动切回 AuthRouter 并跳转/login。export const login (loginAdminData) async (dispatch) { // 1. 请求后端 /login // 2. token.set() 写入 localStorage // 3. storePersist.set(auth, authValue) // 4. dispatch LOGIN_SUCCESS // 5. history.push(/) };另外frontend/src/redux/store.js在创建 Redux store 时会从 localStorage 读取auth作为初始状态这正是刷新页面后依然保持登录的根本原因。后端如何配合/login 与 /logout 接口前端守卫只是第一道防线真正的安全校验在后端。routes/authApi.js暴露了两个核心接口POST /login校验账号密码签发 Token 返回给前端当前使用authControllerDemo演示控制器生产环境应替换为authController的真实登录逻辑POST /logout挂载了isValidToken中间件只有携带合法 Token 的请求才能执行退出操作。isValidToken中间件定义在controllers/authController.js中用于验证 JWT 的合法性。前端路由守卫负责体验后端 Token 校验负责安全两层配合才是完整的 mern-admin 权限体系。常见问题排查路由守卫踩坑指南Q1明明登录成功了刷新后又跳回登录页检查 localStorage 中x-auth-token和auth两个键是否都存在。store.js依赖auth键恢复登录状态如果被其他代码误清空刷新就会掉线。Q2登录页访问了但一直重定向到首页进不去这是 PublicRoute 的正常行为——你的 Token 仍然有效。先执行退出登录清除 Token再访问登录页即可。Q3想新增一个需要登录的页面该怎么做只需三步在frontend/src/pages/创建页面组件 → 在AppRouter.jsx中用lazy引入 → 用PrivateRoute path/xxx component{Xxx} exact /注册守卫会自动生效。Q4Token 过期后会发生什么前端守卫只判断有没有 Token不判断Token 是否过期。过期场景由后端接口返回 401 错误触发前端request/errorHandler.js会统一处理并引导重新登录。总结mern-admin 的路由权限设计可以用一句话概括PrivateRoute 守业务页PublicRoute 守登录页Token 存 localStorageRedux 状态驱动路由切换。这套方案代码简洁、层次清晰非常适合作为 React 后台管理系统路由权限控制的参考模板。相关源码文件索引守卫组件frontend/src/router/PrivateRoute.jsx、frontend/src/router/PublicRoute.jsx路由组织frontend/src/router/AppRouter.jsx、frontend/src/router/AuthRouter.jsx、frontend/src/router/index.jsxToken 管理frontend/src/auth/auth.service.js、frontend/src/auth/cookie.js、frontend/src/config/serverApiConfig.js状态管理frontend/src/redux/auth/actions.js、frontend/src/redux/store.js、frontend/src/redux/storePersist.js后端接口routes/authApi.js、controllers/authController.js如果你也想基于这套架构快速搭建自己的后台管理系统可以克隆仓库后运行npm install npm start启动前端本地开发环境下 API 默认指向http://localhost:8888/api/从登录拦截到 CRUD 模块开箱即用。【免费下载链接】mern-adminMERN Antd Admin MongoDB Nodejs React Node Js Rest Api CRUD Auth项目地址: https://gitcode.com/gh_mirrors/me/mern-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表