暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

角色

晨光 2025-04-24
216

以下是一个基础的角色权限控制代码示例,使用 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>

核心功能说明:

  1. 角色分级

    • 超级管理员:拥有所有权限

    • 普通管理员:管理后台基础功能

    • 普通用户:基础权限

  2. 权限维度

    • 页面权限(路由级)

    • 操作权限(按钮级)

    • 数据权限(接口级)

  3. 实现要点

    • 前端路由守卫校验

    • 后端接口中间件校验

    • 权限数据需要持久化存储

    • 使用JWT进行身份验证

  4. 安全措施

    • 所有权限校验需前后端同时进行

    • 敏感操作需记录日志

    • 使用HTTPS加密传输

实际开发中需要补充:

  1. 完整的用户管理系统

  2. JWT令牌刷新机制

  3. 权限变更后的实时更新

  4. 操作日志记录功能

  5. 数据权限过滤(如不同用户查看不同数据)

测试账号建议:

  • 超级管理员: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>

关键注意事项

  1. 前后端双重校验

    • 前端校验用于用户体验(如隐藏按钮),但不能替代后端校验

    • 后端必须在接口层再次验证角色(示例中的 Node.js 中间件 authMiddleware 实现了这一点)。

  2. 角色存储安全

    • 避免直接将敏感角色信息存在 localStorage,建议从 JWT 解码获取(需配合后端加密)。

  3. 动态权限更新

    • 如果用户权限可能动态变化(如管理员修改用户角色),需及时更新本地存储的角色信息。


扩展建议

  • 添加角色继承
    例如 manager 自动拥有 editor 的权限,可通过角色层级关系实现:

    javascript

    复制

    下载
    const roleHierarchy = {
      'super-admin': ['*'],
      'admin': ['editor', 'viewer'],
      'editor': ['viewer']
    }
    
    function checkPermission(needRoles) {
      const userRoles = getCurrentUserRoles() // 获取用户所有角色
      // 检查用户角色或其继承角色是否包含 needRoles
    }
  • 结合权限表(ACL)
    如果权限涉及具体操作(如 create:userdelete:post),需要更细粒度的权限模型。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论