nest-mysql:RBAC权限管理

本文介绍了基于RBAC(Role-Based Access Control)的权限管理概念,包括用户、角色和权限之间的关系。讨论了不同规模项目中数据库设计的差异,并提出了一种多对多关系的设计方案。详细讲述了如何在NestJS中实现用户、角色、权限的增删改查,以及如何根据用户角色动态显示菜单。同时,提供了后端权限访问的实现逻辑,包括守卫和装饰器的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章问题导向

RBAC权限管理是什么?如何设计数据库?如何实现?

如果你都有了答案,可以忽略本文章,或去nest学习导图寻找更多答案


阅前必知

阅读此文,需要有一定的数据库知识
此文并非最佳实践,只能参考,如果大家有好的设计与代码,欢迎留言


RBAC

RBAC是基于角色的权限访问控制(Role-Based Access Control)
一种数据库设计思想,根据设计数据库设计方案,完成项目的权限管理
在RBAC中,有3个基础组成部分,分别是:用户、角色和权限,权限与角色相关联,用户通过成为适当角色而得到这些角色的权限

  • 权限:具备操作某个事务的能力
  • 角色:一系列权限的集合

如:一般的管理系统中:
销售人员:仅仅可以查看商品信息
运营人员:可以查看,修改商品信息
管理人员:可以查看,修改,删除,以及修改员工权限等等
管理人员只要为每个员工账号分配对应的角色,登陆操作时就只能执行对应的权限或看到对应的页面

权限类型

展示(菜单),如:显示用户列表,显示删除按钮等等…
操作(功能),如:增删改查,上传下载,发布公告,发起活动等等…


数据库设计

数据库设计:可简单,可复杂,几个人使用的系统和几千人使用的系统是不一样的
小型项目:用户表,权限表
中型项目:用户表,角色表,权限表
大型项目:用户表,用户分组表,角色表,权限表,菜单表…


没有角色的设计

只有用户表,菜单表,两者是多对多关系,有一个关联表

缺点:

新建一个用户时,在用户表中添加一条数据
新建一个用户时,在关联表中添加N条数据
每次新建一个用户需要添加1+N(关联几个)条数据
如果有100个用户,每个用户100个权限,那需要添加10000条数据


基于RBAC的设计

用户表和角色表的关系设计:

如果你希望一个用户可以有多个角色,如:一个人即是销售总监,也是人事管理,就设计多对多关系
如果你希望一个用户只能有一个角色,就设计一对多,多对一关系

角色表和权限表的关系设计:

一个角色可以拥有多个权限,一个权限被多个角色使用,设计多对多关系

多对多关系设计

用户表与角色表是多对多关系,角色表与菜单表是多对多关系

在这里插入图片描述


更加复杂的设计

在这里插入图片描述


实现流程

  1. 数据表设计
  2. 实现角色的增删改查
  3. 实现用户的增删改查,增加和修改用户的时候需要选择角色
  4. 实现权限的增删改查
  5. 实现角色与授权的关联
  6. 判断当前登录的用户是否有访问菜单的权限
  7. 根据当前登录账户的角色信息动态显示左侧菜单(前端)

代码实现

这里将实现一个用户,部门,角色,权限的例子:
用户通过成为部门的一员,则拥有部门普通角色的权限,还可以单独给用户设置角色,通过角色,获取权限。
权限模块包括,模块,菜单,操作,通过type区分类型,这里就不再拆分。

关系总览:

用户 - 部门:一对多关系,这里设计用户只能加入一个部门,如果设计可以加入多个部门,设计为多对多关系
用户 - 角色:多对多关系,可以给用户设置多个角色
角色 - 部门:多对多关系,一个部门多个角色
角色 - 权限:多对多关系,一个角色拥有多个权限,一个权限被多个角色使用


数据库实体设计

用户

import {
   
  Column,
  Entity,
  ManyToMany,
  ManyToOne,
  JoinColumn,
  JoinTable,
  PrimaryGeneratedColumn,
} from 'typeorm';
import {
    RoleEntity } from '../../role/entities/role.entity';
import {
    DepartmentEntity } from '../../department/entities/department.entity';

@Entity({
    name: 'user' })
export class UsersEntity {
   
  @PrimaryGeneratedColumn()
  id: number;

  @Column({
   
    type: 'varchar',
    length: 30,
    nullable: false,
    unique: true,
  })
  username: string;

  @Column({
   
    type: 'varchar',
    name: 'password',
    length: 100,
    nullable: false,
    select: false,
    comment: '密码',
  })
  password: string;

  @ManyToMany(() => RoleEntity, (role) => role.users)
  @JoinTable({
    name: 'user_role' })
  roles: RoleEntity[];

  @ManyToOne(() => DepartmentEntity, (department) => department.users)
  @JoinColumn({
    name: 'department_id' })
  department: DepartmentEntity;
}

角色

import {
   
  Entity,
  PrimaryGeneratedColumn,
  Column,
  ManyToMany,
  JoinTable,
} from 'typeorm';
import {
    UsersEntity } from '../../user/entities/user.entity';
import {
    DepartmentEntity } from '../../department/entities/department.entity';
import {
    AccessEntity } from '../../access/entities/access.entity';

@Entity({
    name: 'role' })
export class RoleEntity {
   
  @PrimaryGeneratedColumn()
  id: number;

  @Column({
    type: 'varchar', length: 30 })
  rolename: string;

  @
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值