以下是一个基础的角色权限控制代码示例,使用 Vue3 + Node.js 实现基本的RBAC(基于角色的访问控制)模型:
javascript
复制
下载
// 前端部分(Vue3)
// src/utils/auth.js
// 权限校验方法
export function checkPermission(needRoles) {
const userRole = localStorage.getItem('user-role') || 'guest'
// 超级管理员直接放行
if (userRole === 'super-admin') return true
// 数组格式校验
if (Array.isArray(needRoles)) {
return needRoles.includes(userRole)
}
// 单个权限校验
return needRoles === userRole
}
// 路由权限控制
// src/router.js
router.beforeEach((to) => {
const isAuthenticated = localStorage.getItem('token')
const needRoles = to.meta?.roles
// 需要登录
if (to.meta.requiresAuth && !isAuthenticated) {
return '/login'
}
// 需要权限
if (needRoles) {
if (!checkPermission(needRoles)) {
return '/403' // 无权限页面
}
}
})javascript
复制
下载
// 后端部分(Node.js/Express)
// routes/auth.js
// 中间件:权限校验
const authMiddleware = (roles = []) => {
return (req, res, next) => {
// 从JWT中获取用户信息
const user = req.user
// 超级管理员放行
if (user.role === 'super-admin') return next()
// 验证权限
if (!roles.includes(user.role)) {
return res.status(403).json({ message: '权限不足' })
}
next()
}
}
// 使用示例
router.get('/admin-data',
authMiddleware(['admin', 'super-admin']),
(req, res) => {
// 返回敏感数据
}
)javascript
复制
下载
// 数据库模型示例(Mongoose Schema)
const userSchema = new Schema({
username: String,
password: String,
roles: [{
type: String,
enum: ['user', 'admin', 'super-admin']
}]
})
const permissionSchema = new Schema({
role: String,
resources: [{
name: String, // 资源名称
actions: [String] // 允许的操作
}]
})html
复制
下载
运行
<!-- 前端组件权限控制 -->
<template>
<!-- 页面元素控制 -->
<button v-if="checkPermission(['admin'])">管理按钮</button>
<!-- 指令方式 -->
<button v-permission="'admin'">管理按钮</button>
</template>
<script>
// 自定义权限指令
app.directive('permission', {
mounted(el, binding) {
if (!checkPermission(binding.value)) {
el.parentNode?.removeChild(el)
}
}
})
</script>核心功能说明:
角色分级
超级管理员:拥有所有权限
普通管理员:管理后台基础功能
普通用户:基础权限
权限维度
页面权限(路由级)
操作权限(按钮级)
数据权限(接口级)
实现要点
前端路由守卫校验
后端接口中间件校验
权限数据需要持久化存储
使用JWT进行身份验证
安全措施
所有权限校验需前后端同时进行
敏感操作需记录日志
使用HTTPS加密传输
实际开发中需要补充:
完整的用户管理系统
JWT令牌刷新机制
权限变更后的实时更新
操作日志记录功能
数据权限过滤(如不同用户查看不同数据)
测试账号建议:
超级管理员:superadmin / test1234
普通管理员:admin / test1234
普通用户:user01 / test1234
可以根据实际业务需求扩展权限层级和校验维度,建议配合Element Plus或Ant Design的权限组件使用。
解释export function checkPermission
已深度思考(用时 28 秒)
好的,我现在需要解释用户提供的这个`checkPermission`函数。首先,我得仔细看看这段代码的作用。用户给的是Vue3前端部分的权限校验方法,使用在路由守卫和组件中。
首先,函数的名字是`checkPermission`,接受一个参数`needRoles`。它的目的是检查当前用户是否有访问某个资源或执行某个操作所需的角色。接下来,函数内部从`localStorage`获取用户的角色,默认是'guest'。这说明用户角色信息是存储在客户端的,可能是在登录后设置的。
然后,函数首先检查是否是超级管理员('super-admin'),如果是就直接返回`true`,允许访问。这是因为超级管理员通常拥有所有权限,不需要进一步检查。
接下来,判断`needRoles`是否是数组。如果是,就使用`includes`方法检查用户的角色是否在需要的角色列表中。如果不是数组,就当作单个角色字符串来处理,直接比较是否相等。这样设计让函数更灵活,可以处理单个或多个角色需求的情况。
用户可能想知道这个函数如何被集成到应用中,比如在路由守卫中的使用,或者在组件中用指令或条件渲染控制元素的显示。另外,用户可能关心安全性问题,比如仅在前端做权限控制是否足够,是否需要后端也进行验证。根据代码中的注释,确实提到后端也有中间件进行校验,所以用户应该知道需要前后端同时验证的重要性。
可能存在的疑问点包括:为什么用`localStorage`存储用户角色?这样是否安全?实际上,用户角色应该通过后端验证,并且可能存储在更安全的地方,比如JWT令牌中,但前端可能需要缓存部分信息以方便快速访问。但需要注意,前端存储的信息可能被篡改,因此后端必须进行二次验证。
另外,函数的返回情况需要明确:当用户角色满足时返回`true`,否则`false`。在路由守卫中,返回`true`会允许导航,否则重定向到无权限页面。在组件中,通过`v-if`或自定义指令来控制元素的显示或隐藏。
用户还可能想知道如何处理动态变化的角色,比如用户权限变更后如何实时更新。这时候可能需要监听用户角色变化,或者每次权限检查都从后端获取最新数据,但这可能会影响性能。通常的做法是在登录时获取角色信息,并存放在Vuex或Pinia状态管理库中,而不是每次都读取`localStorage`。
总结起来,这个函数是一个基础的前端权限检查工具,但需要结合后端验证和状态管理来确保系统的安全性。用户需要理解前后端权限校验的必要性,以及如何在实际项目中扩展这个函数的功能,比如添加角色继承、更复杂的权限逻辑等。
export function checkPermission(needRoles) 是一个用于前端权限验证的核心函数,其作用是根据用户的角色判断是否拥有访问特定资源的权限。以下是逐行解析:
函数定义
javascript
复制
下载
export function checkPermission(needRoles) {
// 函数体
}export: 表示这是一个模块导出函数,可在其他文件中通过import { checkPermission } from '@/utils/auth'调用。needRoles: 参数表示当前访问的路由/组件需要的角色,可以是单个角色(如'admin')或角色数组(如['editor', 'manager'])。
获取用户角色
javascript
复制
下载
const userRole = localStorage.getItem('user-role') || 'guest'从
localStorage读取用户角色:通常用户登录后,后端会返回角色信息,前端将其存储在本地(如登录成功时调用localStorage.setItem('user-role', 'admin'))。默认值
'guest':如果未登录或未设置角色,默认视为访客身份。
超级管理员放行
javascript
复制
下载
if (userRole === 'super-admin') return true
超级管理员特权:如果当前用户是
super-admin(最高权限角色),直接跳过后续检查,始终允许访问。安全设计:确保超级管理员不会被权限系统限制。
多角色校验
javascript
复制
下载
if (Array.isArray(needRoles)) {
return needRoles.includes(userRole)
}处理数组类型的
needRoles:
当需要多个角色之一时(例如needRoles = ['editor', 'manager']),检查用户角色是否在数组中。示例:
如果userRole = 'editor',且needRoles = ['editor', 'manager'],返回true。
单角色校验
javascript
复制
下载
return needRoles === userRole
处理字符串类型的
needRoles:
当只需要一个特定角色时(例如needRoles = 'admin'),直接比较用户角色是否匹配。
使用场景示例
1. 路由守卫(控制页面访问)
javascript
复制
下载
// 在路由配置中标记所需角色
const routes = [
{
path: '/admin',
component: AdminPage,
meta: { roles: 'admin' } // 需要 admin 角色
}
]
// 路由守卫中调用 checkPermission
router.beforeEach((to) => {
if (to.meta.roles && !checkPermission(to.meta.roles)) {
return '/403' // 无权限时跳转到错误页
}
})2. 组件内控制元素显示(按钮级权限)
vue
复制
下载
<template>
<button v-if="checkPermission('admin')">删除数据</button>
</template>3. 自定义指令隐藏无权限元素
javascript
复制
下载
// 注册全局指令
app.directive('permission', {
mounted(el, binding) {
if (!checkPermission(binding.value)) {
el.remove() // 直接移除无权限元素
}
}
})
// 在模板中使用
<button v-permission="'admin'">管理按钮</button>关键注意事项
前后端双重校验
前端校验用于用户体验(如隐藏按钮),但不能替代后端校验。
后端必须在接口层再次验证角色(示例中的 Node.js 中间件
authMiddleware实现了这一点)。
角色存储安全
避免直接将敏感角色信息存在
localStorage,建议从 JWT 解码获取(需配合后端加密)。
动态权限更新
如果用户权限可能动态变化(如管理员修改用户角色),需及时更新本地存储的角色信息。
扩展建议
添加角色继承
例如manager自动拥有editor的权限,可通过角色层级关系实现:javascript
复制
下载const roleHierarchy = { 'super-admin': ['*'], 'admin': ['editor', 'viewer'], 'editor': ['viewer'] } function checkPermission(needRoles) { const userRoles = getCurrentUserRoles() // 获取用户所有角色 // 检查用户角色或其继承角色是否包含 needRoles }结合权限表(ACL)
如果权限涉及具体操作(如create:user,delete:post),需要更细粒度的权限模型。




