Permission Explanation
This system supports two permission control modes, dynamically managing page access and button display permissions based on user roles or menu lists.
Permission Control Modes
Overview
The system provides the following two permission control modes:
- Role-based: Controls page access and button display permissions by obtaining user roles through an interface.
- Menu-based: Controls page access and button permissions based on menu structure obtained through an interface.
Configuration Method
The permission control mode is configured through the .env
file in the root directory. Changing the value of VITE_ACCESS_MODE
can switch modes:
frontend
: Frontend control mode, permission control based on role identifiers returned by the backend.backend
: Backend control mode, permission control based on menu lists returned by the backend.
# Permission control mode (frontend | backend)
VITE_ACCESS_MODE=frontend
Frontend Control Mode
Principle
The frontend maintains the menu list. After user login, the interface returns a role identifier (e.g., R_SUPER
). The frontend traverses the menu list based on the role, and if the roles
field of a menu includes that role, access to the corresponding route is allowed. If roles
is not set, all users can access by default.
Configuration Example
The menu configuration file is located at: /src/router/routes/asyncRoutes.ts
[
{
id: 4,
path: "/system",
name: "System",
component: RoutesAlias.Home,
meta: {
title: "menus.system.title",
icon: "",
keepAlive: false,
},
children: [
// Only R_SUPER and R_ADMIN roles can access
{
id: 41,
path: "user",
name: "User",
component: RoutesAlias.User,
meta: {
title: "menus.system.user",
keepAlive: true,
roles: ["R_SUPER", "R_ADMIN"],
},
},
// roles not set, all users can access
{
id: 42,
path: "role",
name: "Role",
component: RoutesAlias.Role,
meta: {
title: "menus.system.role",
keepAlive: true,
},
},
],
},
];
Notes
- Ensure that the role identifiers returned by the interface match the
roles
field in the route table, otherwise users will not be able to access restricted pages.
Backend Control Mode
Principle
The backend generates the menu list. After user login, the interface returns menu data, which the frontend validates and dynamically registers routes to implement permission control.
Data Structure
The menu data structure is defined at: /src/router/routes/asyncRoutes.ts
[
{
id: 4,
path: "/system",
name: "System",
component: RoutesAlias.Home,
meta: {
title: "menus.system.title",
icon: "",
keepAlive: false,
},
children: [
{
id: 41,
path: "user",
name: "User",
component: RoutesAlias.User,
meta: {
title: "menus.system.user",
keepAlive: true,
},
},
{
id: 42,
path: "role",
name: "Role",
component: RoutesAlias.Role,
meta: {
title: "menus.system.role",
keepAlive: true,
},
},
],
},
];
Notes
- The backend returns the menu data structure must match the frontend definition, otherwise it may cause the route registration failure.
Frontend and Backend Control Mode Comparison
Frontend control mode:
- Suitable for systems with fixed roles.
- Backend role changes need to be synchronized with frontend route configuration updates.
- Simple implementation, suitable for small projects.
Backend control mode:
- Suitable for systems with complex permissions.
- Backend returns complete menu list, frontend dynamically registers routes.
- More flexible, but requires consistency between frontend and backend data structures.
Button Permissions Control
Button permissions control supports refined management, dynamically controlling button display through user roles or permission codes returned by the interface.
Permission Codes
Permission codes are applicable to both frontend and backend control modes:
- Frontend control mode: The login interface needs to return a list of permission codes.
- Backend control mode: The menu list needs to include an
authList
field, defining button permissions.
Configuration Example (Backend Control Mode)
[
{
id: 44,
path: "menu",
name: "Menus",
component: RoutesAlias.Menu,
meta: {
title: "menus.system.menu",
keepAlive: true,
authList: [
{ id: 441, title: "Add", auth_mark: "add" },
{ id: 442, title: "Edit", auth_mark: "edit" },
],
},
},
];
Usage Method
Control button display through the hasAuth
method provided by the system:
import { useAuth } from "@/composables/useAuth";
const { hasAuth } = useAuth();
<ElButton v-if="hasAuth('add')">Add</ElButton>
Custom Directive (Backend Control Mode)
In backend control mode, you can control button display based on the auth_mark
of authList
using the custom directive v-auth
.
Configuration Example
[
{
id: 44,
path: "menu",
name: "Menus",
component: RoutesAlias.Menu,
meta: {
title: "menus.system.menu",
keepAlive: true,
authList: [
{ id: 441, title: "Add", auth_mark: "add" },
{ id: 442, title: "Edit", auth_mark: "edit" },
{ id: 443, title: "Delete", auth_mark: "delete" },
],
},
},
];
Usage Method
<ElButton v-auth="'add'">Add</ElButton>
Notes
- Ensure that the roles or permission codes returned by the login interface are consistent with the route table configuration.
- In backend control mode, menu data must strictly follow the structure defined by the frontend.
- When testing permission control, verify that page and button display for different role users meets expectations.