前端权限管理实现:别让用户看到不该看的东西!

前端权限管理实现:别让用户看到不该看的东西!

毒舌时刻

权限管理?听起来就像是前端工程师为了显得自己很专业而特意搞的一套复杂流程。你以为随便加个if语句就能实现权限管理?别做梦了!到时候你会发现,权限逻辑分散在各个组件中,难以维护。

你以为前端权限管理就是最终的安全保障?别天真了!前端权限管理只是为了提高用户体验,真正的安全保障在后端。还有那些所谓的权限管理库,看起来高大上,用起来却各种问题。

为什么你需要这个

  1. 用户体验:良好的权限管理可以为不同角色的用户提供不同的界面,提高用户体验。
  2. 安全性:前端权限管理可以防止用户访问不该访问的功能,提高应用的安全性。
  3. 代码组织:集中的权限管理可以使代码结构更清晰,便于维护。
  4. 可扩展性:良好的权限管理设计可以方便地添加新的角色和权限。
  5. 合规性:某些行业和地区要求应用必须实现严格的权限控制。

反面教材

// 1. 分散的权限逻辑 function AdminPanel() { const user = useUser(); if (user.role !== 'admin') { return <div>Access denied</div>; } return <div>Admin Panel</div>; } function UserProfile() { const user = useUser(); const userId = useParams().id; if (user.role !== 'admin' && user.id !== userId) { return <div>Access denied</div>; } return <div>User Profile</div>; } // 2. 硬编码权限 function Menu() { const user = useUser(); return ( <nav> <ul> <li><a href="/">Home</a></li> {user.role === 'admin' && <li><a href="/admin">Admin</a></li>} {user.role === 'user' && <li><a href="/profile">Profile</a></li>} {user.role === 'guest' && <li><a href="/login">Login</a></li>} </ul> </nav> ); } // 3. 缺少权限检查 function DeleteUser() { const { userId } = useParams(); const handleDelete = async () => { await fetch(`/api/users/${userId}`, { method: 'DELETE' }); }; return <button onClick={handleDelete}>Delete User</button>; } // 4. 权限管理混乱 const roles = { admin: ['create', 'read', 'update', 'delete'], user: ['read', 'update'], guest: ['read'] }; function checkPermission(user, resource, action) { if (!user || !user.role) { return false; } const rolePermissions = roles[user.role]; return rolePermissions.includes(action); } // 5. 缺少权限状态管理 function ProtectedRoute({ children, requiredRole }) { const user = useUser(); if (!user || user.role !== requiredRole) { return <Redirect to="/login" />; } return children; } 

问题

  • 权限逻辑分散在各个组件中,难以维护
  • 硬编码权限,难以扩展
  • 缺少权限检查,存在安全隐患
  • 权限管理混乱,难以理解
  • 缺少权限状态管理,用户体验差

正确的做法

权限管理设计

// 1. 权限配置 const permissions = { roles: { admin: { name: 'Admin', permissions: ['users:create', 'users:read', 'users:update', 'users:delete', 'dashboard:access'] }, user: { name: 'User', permissions: ['users:read', 'users:update', 'profile:access'] }, guest: { name: 'Guest', permissions: ['login:access', 'register:access'] } }, resources: { users: { name: 'Users', actions: ['create', 'read', 'update', 'delete'] }, dashboard: { name: 'Dashboard', actions: ['access'] }, profile: { name: 'Profile', actions: ['access', 'update'] }, login: { name: 'Login', actions: ['access'] }, register: { name: 'Register', actions: ['access'] } } }; // 2. 权限检查函数 function checkPermission(user, resource, action) { if (!user || !user.role) { return false; } const rolePermissions = permissions.roles[user.role]?.permissions || []; const permissionKey = `${resource}:${action}`; return rolePermissions.includes(permissionKey); } // 3. 角色检查函数 function checkRole(user, requiredRole) { if (!user || !user.role) { return false; } return user.role === requiredRole; } // 4. 权限管理钩子 import { useContext } from 'react'; import { AuthContext } from './AuthContext'; export function usePermission() { const { user } = useContext(AuthContext); return { hasPermission: (resource, action) => checkPermission(user, resource, action), hasRole: (role) => checkRole(user, role), user }; } 

路由权限管理

// 1. 受保护的路由组件 import React from 'react'; import { Navigate, useLocation } from 'react-router-dom'; import { usePermission } from './usePermission'; export function ProtectedRoute({ children, requiredPermissions = [], requiredRole = null }) { const { hasPermission, hasRole, user } = usePermission(); const location = useLocation(); // 检查角色 if (requiredRole && !hasRole(requiredRole)) { return <Navigate to="/unauthorized" state={{ from: location }} replace />; } // 检查权限 if (requiredPermissions.length > 0) { const hasAllPermissions = requiredPermissions.every(({ resource, action }) => hasPermission(resource, action) ); if (!hasAllPermissions) { return <Navigate to="/unauthorized" state={{ from: location }} replace />; } } return children; } // 2. 路由配置 import { createBrowserRouter } from 'react-router-dom'; import ProtectedRoute from './ProtectedRoute'; import Home from './pages/Home'; import Admin from './pages/Admin'; import Profile from './pages/Profile'; import Login from './pages/Login'; import Unauthorized from './pages/Unauthorized'; const router = createBrowserRouter([ { path: '/', element: <Home /> }, { path: '/admin', element: ( <ProtectedRoute requiredRole="admin"> <Admin /> </ProtectedRoute> ) }, { path: '/profile', element: ( <ProtectedRoute requiredPermissions={[{ resource: 'profile', action: 'access' }]}> <Profile /> </ProtectedRoute> ) }, { path: '/login', element: <Login /> }, { path: '/unauthorized', element: <Unauthorized /> } ]); 

UI权限管理

// 1. 权限控制组件 import React from 'react'; import { usePermission } from './usePermission'; export function PermissionGuard({ children, resource, action, fallback = null }) { const { hasPermission } = usePermission(); if (!hasPermission(resource, action)) { return fallback; } return children; } // 2. 角色控制组件 import React from 'react'; import { usePermission } from './usePermission'; export function RoleGuard({ children, role, fallback = null }) { const { hasRole } = usePermission(); if (!hasRole(role)) { return fallback; } return children; } // 3. 条件渲染 import React from 'react'; import { PermissionGuard } from './PermissionGuard'; import { RoleGuard } from './RoleGuard'; function UserActions({ userId }) { return ( <div> <PermissionGuard resource="users" action="update"> <button>Edit User</button> </PermissionGuard> <PermissionGuard resource="users" action="delete"> <button>Delete User</button> </PermissionGuard> </div> ); } function AdminMenu() { return ( <RoleGuard role="admin"> <nav> <ul> <li><a href="/admin/users">Users</a></li> <li><a href="/admin/dashboard">Dashboard</a></li> <li><a href="/admin/settings">Settings</a></li> </ul> </nav> </RoleGuard> ); } 

权限状态管理

// 1. AuthContext import React, { createContext, useState, useEffect } from 'react'; export const AuthContext = createContext(); export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // 从 localStorage 或 API 获取用户信息 const fetchUser = async () => { try { const userData = localStorage.getItem('user'); if (userData) { setUser(JSON.parse(userData)); } } catch (error) { console.error('Error fetching user:', error); } finally { setLoading(false); } }; fetchUser(); }, []); const login = async (credentials) => { // 登录逻辑 const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credentials) }); const userData = await response.json(); setUser(userData); localStorage.setItem('user', JSON.stringify(userData)); return userData; }; const logout = () => { setUser(null); localStorage.removeItem('user'); }; return ( <AuthContext.Provider value={{ user, loading, login, logout }}> {children} </AuthContext.Provider> ); } // 2. 权限管理钩子 import { useContext } from 'react'; import { AuthContext } from './AuthContext'; import { checkPermission, checkRole } from './permissions'; export function usePermission() { const { user } = useContext(AuthContext); return { hasPermission: (resource, action) => checkPermission(user, resource, action), hasRole: (role) => checkRole(user, role), user }; } // 3. 权限状态更新 function updateUserPermissions(userId, permissions) { // 更新用户权限 return fetch(`/api/users/${userId}/permissions`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ permissions }) }) .then(response => response.json()) .then(data => { // 更新本地存储的用户信息 const user = JSON.parse(localStorage.getItem('user')); user.permissions = data.permissions; localStorage.setItem('user', JSON.stringify(user)); return data; }); } 

最佳实践

// 1. 权限配置中心化 // permissions.js export const permissions = { roles: { admin: { name: 'Admin', permissions: ['users:create', 'users:read', 'users:update', 'users:delete', 'dashboard:access'] }, user: { name: 'User', permissions: ['users:read', 'users:update', 'profile:access'] }, guest: { name: 'Guest', permissions: ['login:access', 'register:access'] } } }; export function checkPermission(user, resource, action) { if (!user || !user.role) { return false; } const rolePermissions = permissions.roles[user.role]?.permissions || []; const permissionKey = `${resource}:${action}`; return rolePermissions.includes(permissionKey); } // 2. 权限管理组件化 // components/PermissionGuard.jsx import React from 'react'; import { usePermission } from '../hooks/usePermission'; export function PermissionGuard({ children, resource, action, fallback = null }) { const { hasPermission } = usePermission(); if (!hasPermission(resource, action)) { return fallback; } return children; } // 3. 路由权限统一管理 // routes.js import { createBrowserRouter } from 'react-router-dom'; import ProtectedRoute from './components/ProtectedRoute'; import Home from './pages/Home'; import Admin from './pages/Admin'; import Profile from './pages/Profile'; const router = createBrowserRouter([ { path: '/', element: <Home /> }, { path: '/admin', element: ( <ProtectedRoute requiredRole="admin"> <Admin /> </ProtectedRoute> ) }, { path: '/profile', element: ( <ProtectedRoute requiredPermissions={[{ resource: 'profile', action: 'access' }]}> <Profile /> </ProtectedRoute> ) } ]); // 4. 权限检查工具函数 // utils/permission.js export function canAccessRoute(user, route) { if (!route.requiredRole && !route.requiredPermissions) { return true; } if (route.requiredRole) { return user?.role === route.requiredRole; } if (route.requiredPermissions) { return route.requiredPermissions.every(({ resource, action }) => checkPermission(user, resource, action) ); } return false; } // 5. 权限状态管理 // hooks/usePermission.js import { useContext } from 'react'; import { AuthContext } from '../contexts/AuthContext'; import { checkPermission, checkRole } from '../utils/permissions'; export function usePermission() { const { user } = useContext(AuthContext); return { hasPermission: (resource, action) => checkPermission(user, resource, action), hasRole: (role) => checkRole(user, role), user }; } 

毒舌点评

权限管理确实很重要,但我见过太多开发者滥用这个特性,导致应用变得过于复杂。

想象一下,当你为了实现权限管理,创建了大量的组件和钩子,结果导致代码量增加了几倍,这真的值得吗?

还有那些过度使用权限管理的开发者,为了控制每个按钮的权限,而忽略了用户体验,结果导致界面变得支离破碎。

所以,在实现权限管理时,一定要把握好度。不要为了权限管理而权限管理,要根据实际需求来决定权限管理的范围。

当然,对于需要严格权限控制的应用来说,完善的权限管理是必要的。但对于简单的应用,过度的权限管理反而会增加开发成本和维护难度。

最后,记住一句话:权限管理的目的是为了保护用户数据和提高用户体验,而不是为了炫技。如果你的权限管理实现导致用户体验变得更差,那你就失败了。

Read more

毕业设计:基于neo4j的知识图谱的智能问答系统(源码)

毕业设计:基于neo4j的知识图谱的智能问答系统(源码)

一、项目背景 知识图谱作为人工智能领域重要的知识表示与推理技术,近年来已成为实现机器认知智能的核心基础设施。它将海量、异构的实体、属性及其复杂关系,以图结构的形式进行语义化组织与存储,形成了一张能够被计算机理解和处理的“知识网络”。在信息爆炸的时代,传统基于关键词匹配的搜索引擎和问答系统,往往难以理解用户查询背后的深层语义与意图,导致返回结果碎片化、准确性不足,尤其无法有效回答涉及多跳推理、关系路径挖掘的复杂问题。例如,面对“李白最欣赏的诗人是谁?”或“与《静夜思》情感基调相似的杜甫作品有哪些?”这类问题,传统系统往往束手无策。因此,构建能够理解复杂语义、进行关联分析与逻辑推理的智能问答系统,成为提升信息获取效率与智能化水平的关键需求。 在各行业知识密集型应用(如医疗诊断辅助、金融风控、智慧教育等)的驱动下,基于知识图谱的智能问答(KBQA)技术展现了巨大潜力。它通过将自然语言问题解析为对知识图谱的结构化查询,能够直接返回精准、结构化的答案,而非一系列相关网页链接,实现了从“信息检索”到“知识问答”的质变。这一技术路径对于传承与梳理中华优秀传统文化,特别是像古诗词这样蕴含丰富人物、

EgoPoseFormer v2:解决 AR/VR 场景中的第一视角人体动捕问题

目录 一、前言 二、EgoPoseFormer v2 核心内容总结 1. 研究背景与挑战 2. EPFv2 的核心创新 3. 实验结果 4. 应用价值 三、DeepSeek是不是发布过关于图像识别顺序的因果时间注意力机制?         3.1 它们各自是怎么实现的,技术上有没有底层的联系和区别? 1.DeepSeek的“视觉因果流” (空间逻辑重排) 2.Meta EPFv2的“因果时间注意力” (时间逻辑依赖) 3.底层联系与核心区别 4.总结 四、EPFv2和DeepSeek OCR2和SAM2跟踪的区别和联系         4.1 EPFv2和DeepSeek OCR2和SAM2跟踪的区别和联系是什么?         4.2 技术上的相似性 🧩 不同的应用方式:从“基础模块”到“特定智能”

从 Jetson Thor T5000 出发:一篇讲清 NVIDIA 新一代机器人计算平台、产品谱系、架构、性能、软件栈与落地路径

从 Jetson Thor T5000 出发:一篇讲清 NVIDIA 新一代机器人计算平台、产品谱系、架构、性能、软件栈与落地路径

📺 B站:博主个人介绍 📘 博主书籍-京东购买链接*:Yocto项目实战教程 📘 加博主微信,进技术交流群: jerrydev 从 Jetson Thor T5000 出发:一篇讲清 NVIDIA 新一代机器人计算平台、产品谱系、架构、性能、软件栈与落地路径 很多人第一次看到 NVIDIA Jetson Thor T5000,都会下意识把它理解成一块“嵌入式 GPU”或者“Jetson 版显卡”。但严格来说,这个理解并不准确。T5000 不是传统意义上的独立显卡,也不是单独一颗裸芯片,而是 NVIDIA 面向机器人和边缘 AI 推出的高端 Jetson 模组(SoM)产品名;它的核心计算底座来自 Thor 这一代 SoC,而不是上一代的 Orin。

宇树VR遥操与IL——从遥操程序xr_teleoperate到unitree_IL_lerobot:如何基于G1进行manipulation开发

宇树VR遥操与IL——从遥操程序xr_teleoperate到unitree_IL_lerobot:如何基于G1进行manipulation开发

前言 如之前的文章所述,我司「七月在线」正在并行开发多个订单,目前正在全力做好每一个订单,因为保密协议的原因,暂时没法拿出太多细节出来分享 但可以持续解读我们所创新改造或二次开发的对象,即解读paper和开源库「当然 有些paper/库还没开始用,但也可以提前解读,作为关注了解」 而对于我司人形开发的订单,截止到25年4月,背后的机器人多半基于这几家:宇树、智元、傅利叶、乐聚「之所以用的这几家,一半因为我和这些公司熟,一半因为客户已有其中某一家或某几家的本体 需在其基础上做定制开发,如其它厂商看到 有兴趣合作,欢迎私我,比如星动纪元、星海图、众擎等等」 * 通过此文《Fourier-Lerobot——把斯坦福人形动作策略iDP3封装进了Lerobot(含我司七月的idp3落地实践)》可知,傅利叶 把idp3 装进了lerobot * 类似的,宇树 通过此开源库「unitree_IL_lerobot」,也把lerobot 集成了下 该库包含了π0策略 且无论咱们是用傅利叶集成的lerobot—