LogoLogo
github
  • 💪Upupup
  • React
    • hook
    • redux
    • Router
    • umimax+nest.js 实现 权限管理系统
    • umimax + Nest.js 实现权限管理系统
  • Vue
    • effectScope 是干啥的
    • Object.assign()
    • 响应式理解
    • @babel/preset-env 问题
    • 自定义指令
    • 问题及解决
    • 🧐权限管理(动态路由)
  • docker
    • Docker 常用命令
    • Docker部署遇到的问题
    • Docker Compose 常用命令
    • docker修改daemon.json
    • jenkins
    • Jenkinsfile 语法进阶
    • nginx配置
    • 问题
    • 玩转Nginx:轻松为Docker部署的服务添加域名的完美指南
    • Docker部署前后端项目:经验分享与问题解决
  • git
    • command
    • problem
    • rebase实践
  • 前端开发面试题集
    • CSS 面试题
    • 前端工程化面试题
    • HTML 面试题
    • JavaScript 面试题
    • NestJS 面试题
    • Node.js 面试题
    • 性能优化面试题
    • React 面试题
    • 安全面试题
    • Vue 面试题
  • interviewer
    • 计算机网络
    • 性能优化
  • leetcode
    • 算法
      • 分治算法
      • 滑动窗口与双指针
        • 🦸定长滑动窗口
        • 🚴不定长滑动窗口
        • 🚴‍♂️单序列双指针
      • 回溯
      • 二分法
  • nestjs
    • mail
    • mini-order
    • nestjs
    • prisma
    • 登录注册
  • nextjs
    • 用 V0 和 Cursor 实现全栈开发:从小白到高手的蜕变
  • tauri
    • 思路
    • 自动通知应用升级
  • vite
    • vite实现原理
  • webpack
    • 资料
  • 工具
    • Eslint
    • jenkins
    • 关于cicd
  • 微信小程序
    • ScoreDeck
    • h5跳转小程序问题
  • 思路
    • carTool
  • 操作系统学习
    • Linux命令
    • 计算机是如何计数的
    • nginx
      • location
      • try_files
  • 浏览器
    • session、location
    • web crypto
    • 性能监控和错误收集与上报
    • 预请求
  • 知识点整理
    • 知识点整理
  • 面试
    • Promise
    • 备战
    • 数码3
    • 腾娱
    • 腾讯云智
    • 重复请求合并
  • 前端工程化
    • 在 pnpm Monorepo 中使用公共方法包
由 GitBook 提供支持
在本页
  • 前端
  • 获取用户权限信息时机
  • 后端
  • 数据库
  • 总结

这有帮助吗?

在GitHub上编辑
  1. React

umimax + Nest.js 实现权限管理系统

上一页umimax+nest.js 实现 权限管理系统下一页Vue

最后更新于5个月前

这有帮助吗?

前端

在 umi 文档中,我们可以看到有一个称为权限配置的功能,它提供了一套自己的权限管理方案。

权限定义

我们约定将 src/access.ts 作为权限定义文件,在其中可以定义和判断用户是否具有某个权限。

image-20240325095054783

路由权限

通过在路由配置中添加 access 字段,可以判断路由是否有权限访问。

功能权限

使用 useAccess 来获取权限,可以获得所有定义的权限。

获取用户权限信息时机

我们约定在 src/app.tsx 中导出一个 getInitialState 方法,用于初始化信息。例如:

export async function getInitialState(): Promise<{
  user_info?: API.UserInfo;
  roles?: any[];
}> {
  let user_info;
  let roleList;
  const fetchUserInfo = async () => {
    try {
      const token = localStorage.getItem('token');
      const user_info = JSON.parse(localStorage.getItem('user_info') || '');
      if (!token || !user_info) {
        history.push('/login');
      }
      return { token, user_info };
    } catch (error) {
      history.push('/login');
    }
    return { token: null, user_info: null };
  };
  if (history.location.pathname !== '/login') {
    const res = await fetchUserInfo();
    const { roles, ...reset } = res.user_info;
    user_info = reset;
    roleList = roles;
  }
  return {
    user_info,
    roles: roleList,
  };
}

上述代码中,我们在初始化时判断是否为登录页,从而获取存储的信息(权限)。但是,如果登录信息发生改变,则需要重新获取最新的登录信息。因此,在登录时,我们需要重新初始化:

import { useModel } from '@umijs/max';

const { refresh } = useModel('@@initialState');
const handleLogin = async (values: any) => {
  const res = await login(values);
  if (res.data) {
    const { token, user_info } = res.data;
    localStorage.setItem('token', token);
    localStorage.setItem('user_info', JSON.stringify(user_info));
    navigate('/');
    refresh();
  }
};

登录成功后,更新本地缓存并重新初始化,即可获取用户最新的权限。

后端

用户 => 角色 => 权限

用户、角色、权限三个表相互关联。

数据库

user.entity.ts

import { Role } from 'src/role/entities/role.entity';
import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';

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

  @Column({
    comment: '姓名',
    length: 50,
  })
  name: string;

  @Column({
    comment: '密码',
    length: 50,
  })
  password: string;

  @Column({
    comment: '头像',
    length: 1000,
    default: 'https://p26-passport.byteacctimg.com/img/user-avatar/312989b46037c16843b1eb44aea82fa2~180x180.awebp?',
  })
  avator: string;

  @Column({
    comment: '手机号',
    length: 50,
    default:""
  })
  mobile: string;

  @ManyToMany(() => Role)
  @JoinTable({
    name: 'user_role_relation',
  })
  roles: Role[]; // 角色

  @Column({
    comment: '是否可用',
    default: true,
  })
  state: boolean;
}

role.entity.ts

import {
    Column,
    CreateDateColumn,
    Entity,
    JoinTable,
    ManyToMany,
    PrimaryGeneratedColumn,
    UpdateDateColumn,
  } from 'typeorm';
  import { Permission } from '../../permission/entities/permission.entity';
  @Entity()
  export class Role {
    @PrimaryGeneratedColumn()
    id: string;
  
    @Column({
      length: 20,
    })
    name: string;
  
    @CreateDateColumn()
    createTime: Date;
  
    @UpdateDateColumn()
    updateTime: Date;
  
    @ManyToMany(() => Permission)
    @JoinTable({
      name: 'role_permission_relation',
    })
    permissions: Permission[];
  }
  

permission.entity.ts

import {
    Column,
    CreateDateColumn,
    Entity,
    PrimaryGeneratedColumn,
    UpdateDateColumn,
  } from 'typeorm';
  
  @Entity()
  export class Permission {
    @PrimaryGeneratedColumn()
    id: string;
  
    @Column({
      length: 50,
    })
    name: string;
  
    @Column({
      length: 100,
      nullable: true,
    })
    desc: string;

    @CreateDateColumn()
    createTime: Date;
  
    @UpdateDateColumn()
    updateTime: Date;
  }
  

定义好三个表后,基本完成。

在查询用户信息时,我们也需要查询用户的角色和权限:

 this.userRepository.findOne({
      where: { id, state: true },
      select: ['name', 'avator', 'id', 'mobile'],
      relations: ['roles', 'roles.permissions'],
    });

更新用户角色:

async updateUserRoles(createRoleDto) {
    const id = createRoleDto.userId;

    const user = await this.findOne(id);
    if (!user) {
      throw new UnauthorizedException('用户名不存在');
    }
    console.log(user);

    // 查询传入数组roles的全部role实体
    const roles = await this.roleRepository.findBy({
      id: In(createRoleDto.roleIds),
    });
    user.roles = roles
    if (roles.length <= 0) {
      throw new Error('roles not found');
    }

    return this.userRepository.save(user);
  }

权限和角色的查询和修改与用户表类似。通过这样的设计,权限控制就可以实现了。

总结

image-20240325094731789
image-20240325095159867

以上便是我开发的后台管理系统(umimax + Nest + MySQL)的权限设计。通过这个项目,我学习了后端、数据库知识,以及 Docker 和自动化部署。如果你对这些感兴趣,欢迎一起学习,项目地址:。

umimax+nest+mysql