Skip to content

权限系统

概述

Naive Admin Max 提供路由级权限按钮级权限两层权限控制方案。路由级权限通过路由守卫拦截未授权访问;按钮级权限通过 v-auth 指令或 auth() 函数控制页面内按钮的显隐。

路由级权限

路由级权限在路由守卫中实现,未登录用户访问受保护路由会被拦截并重定向至登录页。

typescript
// 路由守卫中的鉴权逻辑
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem(VITE_TOKEN_KEY)

  if (!token && !whiteList.includes(to.path)) {
    // 未登录且不在白名单中 → 重定向到登录页
    next(`/login?redirect=${to.path}`)
  } else {
    next()
  }
})

按钮权限码

后端菜单接口的每个菜单项携带 actionList 字段,包含该页面下可用的操作权限码:

jsonc
{
  "path": "/system/user",
  "component": "templates/system/user/index",
  "actionList": ["create", "update", "delete", "export"]
}

登录后 userStoreactionList 存入 route.meta.actionList,供按钮级权限判断使用。

按钮级权限 — v-auth 指令

v-auth 是注册在全局的自定义指令(src/directives/auth.ts),用于根据权限码控制元素显隐。

字符串语法

判断是否拥有单个权限码:

vue
<template>
  <!-- 拥有 'create' 权限码时显示 -->
  <NButton v-auth="'create'">新增</NButton>
</template>

数组语法

判断是否拥有数组中任意一个权限码:

vue
<template>
  <!-- 拥有 'update' 或 'delete' 任一权限时显示 -->
  <NButton v-auth="['update', 'delete']">操作</NButton>
</template>

对象语法

更精细的控制,支持取反逻辑:

vue
<template>
  <!-- 必须同时拥有 'create' 和 'update' 权限 -->
  <NButton v-auth="{ code: ['create', 'update'], mode: 'every' }">
    批量操作
  </NButton>
</template>

auth() 工具函数

当需要在非模板代码(如 render 函数、组合式函数)中判断权限时,使用 auth() 函数:

typescript
import { auth } from '@/directives/auth'

// 判断是否有 'delete' 权限
if (auth('delete')) {
  // 显示删除按钮
}

// 在操作列配置中使用
const rowActions = useRowActions({
  inline: [
    {
      label: '删除',
      type: 'error',
      auth: 'delete', // 内部调用 auth() 判断
      onClick: (row) => handleDelete(row),
    },
  ],
})

权限判断来源

v-authauth() 都从当前路由的 meta.actionList 中读取权限码列表。如果 actionList 包含目标权限码,则视为有权限。

注意

按钮级权限仅控制 UI 显隐,不替代后端鉴权。后端接口仍需做权限校验,防止直接调用接口绕过前端限制。

Released under the MIT License.