谷粒学院——第二十章、权限管理

news2024/11/25 11:43:11

一、权限管理需求描述

不同角色的用户登录后台管理系统拥有不同的菜单权限与功能权限,权限管理包含三个功能模块:菜单管理、角色管理和用户管理
image.png

1、菜单管理

(1)菜单列表:使用树形结构显示菜单列表
(2)添加菜单:点击添加菜单,弹框进行添加
(3)修改菜单
(4)删除菜单

2、角色管理

(1)角色列表:实现角色的条件查询带分页功能
(2)角色添加
(3)角色修改
(4)角色删除

  • 普通删除
  • 批量删除

(5)角色分配菜单

3、用户管理

(1)用户列表
(2)用户添加
(3)用户修改
(4)用户删除
(5)用户分配角色

4、表与表之间的关系

image.png

二、spring security介绍

1、框架介绍

Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。
(1)用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
(2)用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
Spring Security其实就是用filter,多请求的路径进行过滤。
(1)如果是基于Session,那么Spring-security会对cookie里的sessionid进行解析,找到服务器存储的sesion信息,然后判断当前用户是否符合请求的要求。
(2)如果是token,则是解析出token,然后将当前请求加入到Spring-security管理的权限信息中去

2、认证与授权实现思路

如果系统的模块众多,每个模块都需要就行授权与认证,所以我们选择基于token的形式进行授权与认证,用户根据用户名密码认证成功,然后获取当前用户角色的一系列权限值,并以用户名为key,权限列表为value的形式存入redis缓存中,根据用户名相关信息生成token返回,浏览器将token记录到cookie中,每次调用api接口都默认将token携带到header请求头中,Spring-security解析header头获取token信息,解析token获取当前用户名,根据用户名就可以从redis中获取权限列表,这样Spring-security就能够判断当前请求是否有权限访问
image.png

三、整合spring security

1、复制工具类到common_utils

image.png

2、在common下创建spring_security模块

3、在spring_security引入相关依赖

<dependencies>
  <dependency>
    <groupId>com.atguigu</groupId>
    <artifactId>common_utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>
  <!-- Spring Security依赖 -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>

  <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
  </dependency>
</dependencies>

4、代码结构说明

image.png

5、springsecurity详细解答

看到这不理解吧
我在这篇文章中做了解释

四、开发权限管理接口 – 后端

1、在service模块下创建子模块service-acl

2、创建权限管理相关的表

image.png

3、复制权限管理接口代码

4、在service_acl模块中引入依赖

这里我们整合了spring security 模块

<dependencies>
  <dependency>
    <groupId>com.atguigu</groupId>
    <artifactId>spring_security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
  </dependency>
</dependencies>

5、编写application.properties配置文件

# 服务端口
server.port=8009
# 服务名
spring.application.name=service-acl

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

spring.redis.host=127.0.0.1
ing.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000

spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
#最小空闲

#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/aclservice/mapper/xml/*.xml

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

6、开发权限管理接口

(1)查询所有菜单

PermissionController类

@ApiOperation(value = "查询所有菜单")
    @GetMapping
    public R indexAllPermission() {
        List<Permission> list =  permissionService.queryAllMenu();
        return R.ok().data("children",list);
    }

PermissionServiceImpl 类

//获取全部菜单
@Override
    public List<Permission> queryAllMenu() {
    //根据id排序
    QueryWrapper<Permission> wrapper = new QueryWrapper<>();
    wrapper.orderByDesc("id");

    //查询菜单所有数据
    List<Permission> permissionList = baseMapper.selectList(wrapper);

    //把查询所有菜单list集合按要求进行封装
    List<Permission> result = bulidPermission(permissionList);
    return result;
}

//使用递归方法建菜单
//把返回所有菜单list集合进行封装的方法
public static List<Permission> bulidPermission(List<Permission> permissionList) {
    //创建list集合,用于数据最终封装
    List<Permission> finalNode = new ArrayList<>();
    //把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
    for(Permission permissionNode : permissionList) {
        //得到顶层菜单 pid=0菜单
        if("0".equals(permissionNode.getPid())) {
            //设置顶层菜单的level是1
            permissionNode.setLevel(1);
            //根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
            finalNode.add(selectChildren(permissionNode,permissionList));//permissionNode一级菜单,permissionList所有菜单
        }
    }
    return finalNode;//最终菜单
}

//递归查找子节点
private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
    //1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
    permissionNode.setChildren(new ArrayList<Permission>());

    //2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
    for(Permission it : permissionList) {
        //判断 id和pid值是否相同
        if(permissionNode.getId().equals(it.getPid())) {
            //把父菜单的level值+1
            int level = permissionNode.getLevel()+1;
            it.setLevel(level);
            //如果children为空,进行初始化操作
            if(permissionNode.getChildren() == null) {
                permissionNode.setChildren(new ArrayList<Permission>());
            }
            //把查询出来的子菜单放到父菜单里面
            permissionNode.getChildren().add(selectChildren(it,permissionList));
        }
    }
    return permissionNode;
}

Permission实体类添加的属性

@ApiModelProperty(value = "层级")
    @TableField(exist = false)
    private Integer level;

@ApiModelProperty(value = "下级")
    @TableField(exist = false)
    private List<Permission> children;

@ApiModelProperty(value = "是否选中")
    @TableField(exist = false)
    private boolean isSelect;

(2)递归删除菜单

PermissionController 类

@ApiOperation(value = "递归删除菜单")
    @DeleteMapping("remove/{id}")
    public R remove(@PathVariable String id) {
        permissionService.removeChildById(id);
        return R.ok();
    }

PermissionServiceImpl 类

@Override
    public void removeChildById(String id) {
        List<Permission> permissionList = baseMapper.selectList(null);
		deleteTree(permissionList, id);
}

//递归删除
@Transactional
    public void deleteTree(List<Permission> lists, String pid) {
    for (Permission son : lists) {
        if (son.getPid().equals(pid)) {
            //递归删除
            deleteTree(lists, son.getId());
        }
    }
    baseMapper.deleteById(pid);
    //同时删除角色菜单表数据
    QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
    wrapper.eq("permission_id", pid);
    rolePermissionService.remove(wrapper);
}

(3)给角色分配权限

PermissionController 类

@ApiOperation(value = "给角色分配权限")
    @PostMapping("/doAssign")
    public R doAssign(String roleId,String[] permissionId) {
        permissionService.saveRolePermissionRealtionShip(roleId,permissionId);
        return R.ok();
    }

PermissionServiceImpl 类

//给角色分配权限
@Override
    @Transactional
    public void saveRolePermissionRealtionShip(String roleId, String[] permissionIds) {

    rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));

    List<RolePermission> rolePermissionList = new ArrayList<>();
    for (String permissionId : permissionIds) {
        RolePermission rolePermission = new RolePermission();
        rolePermission.setRoleId(roleId).setPermissionId(permissionId);

        rolePermissionList.add(rolePermission);
    }
    rolePermissionService.saveBatch(rolePermissionList);
}

这里我们只写了比较重要的代码,还有一些看我后面上传的代码中有。

五、权限管理 – 前端

1、到源码中找到整合前端代码,替换项目中前端项目内容

image.png

2、在前端项目中下载依赖

npm install --save vuex-persistedstate 

3、需要修改两个地方

(1)修改router文件夹里面index.js里面路径和vue文件地址
image.png
(2)修改数据库菜单路径和页面地址
image.png

4、修改config/dev.env.js地址

端口号改为网关的地址
image.png

5、测试功能

启动redis和nacos

6、权限整合是spring security执行过程

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

故障分析 | MySQL 主从延时值反复跳动

作者&#xff1a;徐文梁 爱可生DBA成员&#xff0c;负责客户项目的需求和维护。目前在数据库新手村打怪升级中。喜欢垂钓&#xff0c;如果你也喜欢垂钓&#xff0c;可以约个晴好天气&#xff0c;咱们一边钓鱼一边聊聊数据库&#xff0c;岂不快哉。 本文来源&#xff1a;原创投稿…

idea常用配置及问题解决

文章目录一、配置1.字体与行高2.快捷键(eclipse)3.Git配置4.添加Github账户5.设置字符集:UTF-86.设置自动编译7.顶部工具栏左侧显示8.配置.gitignore文件9.忽略、不显示文件10.显示包的层级结构(树结构)11.修改 Generate 快捷键12.设置代码提示忽略大小写13.去除pom.xml中依赖的…

【Go】入门Go语言

【Go】入门Go语言 前言 Go这门语言在当下已经越来越火热了&#xff0c;无论是后端开发岗&#xff0c;还是逆向安全岗位&#xff0c;亦或是渗透领域&#xff0c;乃至脚本小子…各个领域的人员都在分Go这一杯羹。 并且在最近越来越多的CTF比赛中&#xff0c;Go逆向、Go pwn&am…

idea配置maven步骤及常见问题

idea 配置maven步骤及常见问题maven 下载maven的配置配置系统环境变量maven本地仓库配置和镜像加速idea 中配置maven的设置常见问题&#xff0c;每次新建项目需要重新手动配置maven的解决maven 下载 首先&#xff0c;进入它的官网&#xff1a;链接: https://maven.apache.org/…

Find My资讯|被盗的AirPods通过苹果Find My找回并抓到盗窃者

美国一位盗窃案的受害者&#xff0c;他在圣安东尼奥莱昂谷的家中发现有人偷走了他的汽车后决定亲手将小偷捉住。打开Find My&#xff0c;他看到其中被拿走的AirPods显然是停在35号州际公路上的一个旅行站。在前往该站并发现一辆SUV里有五个人后&#xff0c;阿林顿打电话给警察寻…

谷粒学院——第二十二章、Jenkins可持续自动部署

一、安装内容 Jenkins&#xff08;本文主要安装&#xff09;、Maven、Git、JDK Jenkins与Github配合实现持续集成需要注意以下几点&#xff1a; ①Jenkins要部署到外网&#xff0c;因为内网Github是无法访问到的&#xff08;走过的坑&#xff01;&#xff09;&#xff0c;这里…

Usaco Training 刷怪旅 第三层 第六题:Ski Course Design

说实话&#xff0c;一开始看上一题的时候觉得太恶心就先来做这道&#xff0c;所以这题其实比上一题早做出来&#xff08;&#xff09; Farmer John has N hills on his farm (1 < N < 1,000), each with an integer elevation in the range 0 .. 100. In the winter, sin…

MVC MVVM架构

注&#xff1a;个人理解仅供参考1、MVC优点&#xff1a;1、模块独立&#xff0c;解耦缺点&#xff1a;1、厚重的ViewController2、遗失&#xff08;无处安放&#xff09;的网络逻辑3、较差的可测试性图2、MVVM优点1、低耦合&#xff1a;View可以独立于Model变化和修改&#xff…

【HybirdCLR】入门记录-Unity2021 + WebGL

目录前言环境案例学习先PC平台试一下转为WebGL平台动手做一个demo功能基本工作流程搭建环境构建项目补充致谢参考资料前言 之前一直有听说热更新技术&#xff0c;于是找点时间来研究一下热更新技术的使用。热更新的实现方式有很多种&#xff0c;这里笔者记录一下自己学习Hybir…

基于开源体系的云原生微服务治理实践与探索

作者&#xff1a;董艺荃&#xff5c;携程服务框架负责人 携程微服务产品的发展历程 携程微服务产品起步于 2013 年。最初&#xff0c;公司基于开源项目 ServiceStack 进行二次开发&#xff0c;推出 .Net 平台下的微服务框架 CServiceStack。 2014 年&#xff0c;公司推出 Jav…

【PhD Debate —11】矛与盾的对决——神经网络后门攻防

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;2022年7月9日&#xff0c;AI TIME组织了Ph.D. Debate第十一期&#xff0c;题为“矛与盾的对决——神经网络后门攻防”的研讨活动&#xff0c;特别邀请了宾夕法尼亚州州立大学电子工程系博士生向臻、清华大学博士生…

区块链基础知识(一)

参考书籍《区块链原理、设计与应用》 基本原理 比特币网络工作流程 技术的演化与分类 分布式共识 交易性能 扩展性问题 数据库和存储系统 数据库也是区块链中重要的一环 分布式系统核心问题 单节点结构演变为分布式系统&#xff0c;首先遇到的问题就是一致性的保障。 一致性问…

小程序开发经验分享(5)-全屏展示小程序

小程序的 navigationBar,有APP开发经验的同学应该知道,navigationBar也就是程序最顶部的一条,我们同常的开发页面,也都是在navigationBar下方的主体区用标签开发UI部分 如下面两个图片,左边的翻译君官方小程序中上面就有这样一个navigationBar用于展示自己的title和菜单按…

K8s 认证工程师 CKA 考题分析和题库练习(下)

目录 10、考核知识&#xff1a;检查可用节点数量 题目内容 题目内容中文解释 做题解答 11、考核知识&#xff1a;一个 Pod 封装多个容器 题目内容 题目内容中文解释 官方文档搜索关键字&#xff1a;pod ​编辑做题解答 12、考核知识&#xff1a;持久卷 PersistentV…

Mac M1芯片 搭建RocketMQ

Mac M1芯片 搭建RocketMQ RocketMQ需要启动三个组件 1、nameserver 路由中心,为整个MQ集群提供服务协调与治理 2、broker 提供消息的转发和存储功能 3、console 控制台面板工具 1、下载RocketMQ https://rocketmq.apache.org/dowloading/releases/ 选择 Binary: rocketmq-all-4…

对外投资追踪汇率数据金融开放指数

一、2005-2020年中国全球投资追踪数据 “中国全球投资跟踪”&#xff08;China Global Investment Tracker&#xff09;数据库&#xff0c;由美国企业研究所于1月28日发布。该数据库是唯一一套涵盖中国全球投资和建设的综合数据集&#xff0c;同时使用分别记录和汇总记录两种方…

这几个算法可视化网站,太牛了!

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/Tyson0314/Java-…

深入 Android 底层服务(service)

前言 我们都知道&#xff0c;字节最近发布了PICO&#xff14;VR眼镜&#xff0c;我买了一个&#xff0c;体验还行。因为我也是做VR眼镜的Android应用层开发的&#xff0c;所以想把自己项目中遇到的一些Android技术分享给读者。近些年随着VR眼镜的兴起&#xff0c;Android的的服…

项目经理跨部门沟通,如何避免踢皮球?

软件项目干系人越多&#xff0c;沟通成本也就越高&#xff0c;非常容易出现相互提皮球的现象。那么如何高效沟通&#xff1f; 1、划分干系人 不同干系人不同策略 软件项目涉及干系人众多&#xff0c;项目不经理不可能对每一个人进行详细沟通&#xff0c;那么我们需要将干系人的…

如何把优化Docker镜像大小

什么是Docker Docker是一个开源的虚拟化平台&#xff0c;可以让开发人员将应用程序和依赖项打包在轻量级容器中&#xff0c;然后可以轻松地在任何环境中运行。这样&#xff0c;开发人员可以将容器作为独立的可移植单元在不同的环境中部署和运行应用程序&#xff0c;而不用担心环…