8.0 KiB
8.0 KiB
前端权限控制使用指南
📋 概述
前端权限控制系统已经完善,支持:
- ✅ 自动获取用户信息(刷新页面时)
- ✅ 角色权限检查
- ✅ 权限码检查
- ✅ 路由守卫自动验证
🔧 已修复的问题
1. 认证状态判断
- 之前:
isAuthenticated = !!token && !!user(刷新页面时 user 为 null 导致判断失败) - 现在:
isAuthenticated = !!token(只要有 token 就认为已认证)
2. 自动获取用户信息
- 之前: 刷新页面后用户信息丢失
- 现在:
- 应用启动时自动获取(
main.ts) - 路由守卫中自动获取(如果 token 存在但 user 不存在)
- 应用启动时自动获取(
3. 权限检查
- 之前: 只检查
requiresAuth,没有角色和权限检查 - 现在: 支持角色和权限检查
🎯 使用方法
1. 在路由中配置权限
使用角色控制
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
roles: ["super_admin", "admin"], // 需要 super_admin 或 admin 角色
},
}
使用权限控制
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
permissions: ["user:read"], // 需要 user:read 权限
},
}
同时使用角色和权限
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
roles: ["admin"], // 需要 admin 角色
permissions: ["user:read"], // 并且需要 user:read 权限
},
}
注意: 如果同时设置了 roles 和 permissions,需要同时满足两者。
2. 在组件中使用权限
<template>
<div>
<!-- 根据角色显示 -->
<a-button v-if="authStore.hasRole('super_admin')" @click="deleteAll">
删除所有
</a-button>
<!-- 根据权限显示 -->
<a-button v-if="authStore.hasPermission('user:create')" @click="createUser">
创建用户
</a-button>
<!-- 检查多个角色 -->
<a-button
v-if="authStore.hasAnyRole(['admin', 'editor'])"
@click="editUser"
>
编辑用户
</a-button>
<!-- 检查多个权限 -->
<a-button
v-if="authStore.hasAnyPermission(['user:update', 'user:delete'])"
@click="manageUser"
>
管理用户
</a-button>
</div>
</template>
<script setup lang="ts">
import { useAuthStore } from "@/stores/auth";
const authStore = useAuthStore();
</script>
3. Store 方法说明
hasRole(role: string): boolean
检查用户是否有指定角色
if (authStore.hasRole("super_admin")) {
// 用户是超级管理员
}
hasPermission(permission: string): boolean
检查用户是否有指定权限
if (authStore.hasPermission("user:create")) {
// 用户可以创建用户
}
hasAnyRole(roles: string[]): boolean
检查用户是否有任一指定角色
if (authStore.hasAnyRole(["admin", "editor"])) {
// 用户是 admin 或 editor
}
hasAnyPermission(permissions: string[]): boolean
检查用户是否有任一指定权限
if (authStore.hasAnyPermission(["user:create", "user:update"])) {
// 用户可以创建或更新用户
}
🔄 工作流程
1. 应用启动流程
应用启动
↓
检查 localStorage 中是否有 token
↓
如果有 token,调用 fetchUserInfo() 获取用户信息
↓
用户信息包含 roles 和 permissions
↓
应用挂载完成
2. 路由导航流程
用户访问路由
↓
路由守卫 beforeEach
↓
检查 token 是否存在
↓
如果 token 存在但 user 不存在 → 自动获取用户信息
↓
检查 requiresAuth → 是否需要登录
↓
检查 roles → 是否有指定角色
↓
检查 permissions → 是否有指定权限
↓
允许/拒绝访问
3. 登录流程
用户登录
↓
调用 authApi.login()
↓
返回 token 和 user 信息(包含 roles 和 permissions)
↓
保存 token 到 localStorage
↓
保存 user 到 store
↓
跳转到目标页面
📝 路由配置示例
完整的路由配置示例
const routes: RouteRecordRaw[] = [
{
path: "/login",
name: "Login",
component: () => import("@/views/auth/Login.vue"),
meta: { requiresAuth: false },
},
{
path: "/",
component: () => import("@/layouts/BasicLayout.vue"),
redirect: "/workbench",
meta: { requiresAuth: true },
children: [
{
path: "workbench",
name: "workbench",
component: () => import("@/views/workbench/Index.vue"),
meta: {
title: "仪表盘",
requiresAuth: true,
},
},
{
path: "system/users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
permissions: ["user:read"], // 需要查看用户权限
},
},
{
path: "system/roles",
name: "SystemRoles",
component: () => import("@/views/system/roles/Index.vue"),
meta: {
title: "角色管理",
requiresAuth: true,
roles: ["super_admin", "admin"], // 需要管理员角色
},
},
],
},
];
🎨 实际应用场景
场景 1: 根据权限显示菜单
<template>
<a-menu>
<a-menu-item v-if="authStore.hasPermission('user:read')">
<router-link to="/system/users">用户管理</router-link>
</a-menu-item>
<a-menu-item v-if="authStore.hasRole('admin')">
<router-link to="/system/roles">角色管理</router-link>
</a-menu-item>
</a-menu>
</template>
场景 2: 根据权限显示按钮
<template>
<a-table>
<template #action="{ record }">
<a-space>
<a-button
v-if="authStore.hasPermission('user:update')"
@click="edit(record)"
>
编辑
</a-button>
<a-button
v-if="authStore.hasPermission('user:delete')"
danger
@click="remove(record)"
>
删除
</a-button>
</a-space>
</template>
</a-table>
</template>
场景 3: 组合权限检查
<template>
<!-- 需要同时满足角色和权限 -->
<a-button
v-if="authStore.hasRole('admin') && authStore.hasPermission('user:delete')"
@click="deleteAll"
>
批量删除
</a-button>
</template>
⚠️ 注意事项
1. 路由守卫是异步的
路由守卫使用了 async/await,确保在检查权限前用户信息已加载。
2. 权限检查顺序
- 认证检查(
requiresAuth) - 角色检查(
roles) - 权限检查(
permissions)
3. 403 页面
如果没有权限,会跳转到 /403 页面。你可以自定义这个页面。
4. 权限更新
如果用户权限发生变化,需要:
- 重新登录,或
- 调用
authStore.fetchUserInfo()刷新用户信息
🔍 调试技巧
1. 查看当前用户信息
import { useAuthStore } from "@/stores/auth";
const authStore = useAuthStore();
console.log("用户信息:", authStore.user);
console.log("角色:", authStore.user?.roles);
console.log("权限:", authStore.user?.permissions);
2. 检查权限
console.log("是否有 admin 角色:", authStore.hasRole("admin"));
console.log("是否有 user:create 权限:", authStore.hasPermission("user:create"));
📚 总结
现在权限控制系统已经完善:
- ✅ 自动获取用户信息 - 刷新页面不会丢失
- ✅ 路由权限检查 - 支持角色和权限控制
- ✅ 组件权限检查 - 可以在组件中使用权限方法
- ✅ 类型安全 - TypeScript 类型定义完善
可以开始使用权限控制功能了!