spring boot 登入权限RBAC模式

news/2025/3/25 8:42:05/

首先准备好5张表

user_info表,用户的信息表

role表,角色表(比如超级管理员、管理员、审核员、采购......)

创建user_role表,user_info表,role表的中间表

注意了,role_id和user_id是        user_info表和role表的关联id 

auth_info表 菜单权限

创建roler_ayth表 ,auth表和role表的中间表

注意了,role_id和auth_id是        role_id表和auth_info表的关联id 

也就是用户和角色有和中间表,角色和菜单表有个中间表 


有表了我们开始做菜单树

1、创建实体类,mapper,service实现接口,impl实现类,映射文件mapper

博主用的是MyBatisCodeHelperPro插件,用逆向工程也就是从菜单树开始查询(MybatisX、Mybatis puls、Mybatis..插件必须卸载会冲突的,新手可以试用7天,价格在59人民币一年这样)

首先链接数据源

 

 找到菜单权限auth_info表  右键

最后确定


 这就是我们说的实体类,mapper,service实现接口,impl实现类,映射文件mapper


2、AuthInfoMapper类

java">package com.pn.service;import com.pn.entity.AuthInfo;
import java.util.List;public interface AuthInfoService{public List<AuthInfo> queryAuthInfoByUid(Integer userId);
}

3、AuthInfoMapper.xml

java"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.AuthInfoMapper"><!--  根据用户ID查用户权限菜单--><!-- 得出合法行这个是固定的: select t3.* from user_role t1, role_auth t2, auth_info t3where t1.role_id = t2.role_id and t2.auth_id = t3.auth_id and t1.user_id = #{userId} -->
<!--  其他条件根据自己的表来,比如博主这个t3.auth_state=1是说明开启的 --><select id="getAuthInfoByUid" resultType="AuthInfo">select t3.* from user_role t1, role_auth t2, auth_info t3where t1.role_id = t2.role_id and t2.auth_id = t3.auth_idand t3.auth_state = 1and t3.auth_type != 3and t1.user_id = #{userId}</select>
</mapper>

4、AuthInfoService 实现类接口

java">package com.pn.service;import com.pn.entity.AuthInfo;
import java.util.List;public interface AuthInfoService{public List<AuthInfo> queryAuthInfoByUid(Integer userId);
}

5、AuthInfoServiceImpl 实现类

java">package com.pn.service.impl;import com.alibaba.fastjson.JSON;
import com.pn.entity.AuthInfo;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.pn.mapper.AuthInfoMapper;
import com.pn.service.AuthInfoService;
import org.springframework.util.StringUtils;import java.time.Duration;
import java.util.ArrayList;
import java.util.List;@Service
public class AuthInfoServiceImpl implements AuthInfoService{@Autowiredprivate AuthInfoMapper authInfoMapper;// 0库 博主用的是自己封装好的redis分库的,可以自己用自己的,也可以不用//@Autowired//@Qualifier("reactiveRedisTemplateDb0")//private ReactiveRedisTemplate<String, Object> redis;/***  查询用户菜单数的业务方法* @param userId* @return*/@Overridepublic List<AuthInfo> queryAuthInfoByUid(Integer userId) {//先从redis查缓存,因为权限很少改动,所有放缓存,//String authTerrJson = (String) redis.opsForValue().get("authTree:"+userId).block();//有的话string转json给前端//if (StringUtils.hasText(authTerrJson)) {//    return JSON.parseArray(authTerrJson, AuthInfo.class);//}//查redis无缓存,查数据库List<AuthInfo> allauthInfo = authInfoMapper.getAuthInfoByUid(userId);// 将查出的菜单List<AuthInfo>转成菜单树,需要递归算法List<AuthInfo> authInfoList = allAuthToAuthTree(allauthInfo,0);// 查出的菜单树存redis,并设置有效期//redis.opsForValue().set("authTree:"+userId, JSON.toJSONString(authInfoList), Duration.ofSeconds(3600*24)).subscribe();return authInfoList;}// 递归算法,必须是私有的private List<AuthInfo> allAuthToAuthTree(List<AuthInfo> allauthInfo, Integer pid) {//查出一级菜单List<AuthInfo> allauthInfoList = new ArrayList<>();for (AuthInfo authInfo : allauthInfo) {if (authInfo.getParentId().equals(pid)) {allauthInfoList.add(authInfo);}}// 从一级菜单拿二级菜单for (AuthInfo firstauthInfo : allauthInfoList) {List<AuthInfo> firstauthInfoList = allAuthToAuthTree(allauthInfo,firstauthInfo.getAuthId());firstauthInfo.setChildAuth(firstauthInfoList);}//返回菜单树return allauthInfoList;}
}

6、AuthInfo实体类

java">package com.pn.entity;import java.io.Serializable;
import java.util.Date;
import java.util.List;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 权限表*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthInfo implements Serializable {private Integer authId;/*** 父id为空或为0,表示一级权限*/private Integer parentId;private String authName;private String authDesc;private Integer authGrade;/*** 1 模块 、2  列表、 3  按钮*/private String authType;private String authUrl;private String authCode;private Integer authOrder;/*** 1 启用 、0 禁用*/private String authState;private Integer createBy;private Date createTime;private Integer updateBy;private Date updateTime;/***  存放当前菜单下的所有子菜单*/private List<AuthInfo> childAuth;
}

7、最后控制器,更具自己的前端给到的数据写

java">   /*** 用户权限*/// 注入UserService接口@Autowiredprivate AuthInfoService authInfoService;
@RequestMapping("user/auth-list")public Result userAuthTree(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token) {//获取到token,并解析CurrentUser currentUser = tokenUtil.getCurrentUser(token);// 主要是这个  接口传递用户idList<AuthInfo> authInfos = authInfoService.queryAuthInfoByUid(currentUser.getUserId());return Result.ok("获取成功",authInfos);}


http://www.ppmy.cn/news/1582423.html

相关文章

用 pytorch 从零开始创建大语言模型(零):汇总

用 pytorch 从零开始创建大语言模型&#xff08;零&#xff09;&#xff1a;汇总 本系列官方代码库&#xff1a;https://github.com/rasbt/LLMs-from-scratch/tree/main 官方书籍&#xff1a;Build a Large Language Model (From Scratch) 本系列文章&#xff1a; 用 pytorc…

编程语言选择分析:C#、Rust、Go 与 TypeScript 编译器优化

编程语言选择分析&#xff1a;C#、Rust、Go 与 TypeScript 编译器优化 在讨论编程语言的选择时&#xff0c;特别是针对微软的 C# 和 Rust&#xff0c;以及谷歌的 Go 语言&#xff0c;以及微软试图通过 Go 来拯救 TypeScript 编译器的问题&#xff0c;我们可以从多个角度来分析和…

计算机的基本组合和工作原理

计算机的基本组成和工作原理可以概括为以下几个核心部分&#xff1a; 一、计算机的基本组成&#xff08;冯诺依曼体系结构&#xff09; 现代计算机基于冯诺依曼体系结构&#xff0c;主要由以下五大部件组成&#xff1a; 控制器&#xff08;Control Unit, CU&#xff09; 功能&…

dify创建第一个Agent

1、首先LLM模型必须支持 Function Calling 由于deepseek-R1本地化部署时还不支持&#xff0c;所以使用 qwq模型。 2、创建空白 Agent 3、为Agent添加工具 4、测试 当未添加时间工具时 询问 时间 如下 5、开启时间工具 询问如下

Java 中 ArrayList 的底层数据结构及相关分析

Java 中 ArrayList 的底层数据结构及相关分析 1. ArrayList 的底层数据结构 ArrayList 是 Java 中基于 动态数组 实现的 可变长度 集合类&#xff0c;属于 java.util 包中的 List 接口实现之一。底层使用一个 Object[] 数组存储元素&#xff0c;其核心特点是 支持随机访问&am…

【概念】Node.js,Express.js MongoDB Mongoose Express-Validator Async Handler

1. Node.js 定义&#xff1a;Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff0c;允许你在服务器端运行 JavaScript 代码。作用&#xff1a;它使得开发者可以使用 JavaScript 编写服务器端代码&#xff0c;从而实现前后端使用同一种语言。比喻&#xff1a…

开源模型应用落地-LangGraph101-多智能体协同实践(六)

一、前言 随着人工智能技术的快速发展,如何高效处理复杂任务成了 AI 系统的一大挑战。传统的线性架构在面对多轮对话和动态决策时常常显得无能为力。而 LangGraph 这种多智能体合作框架的出现,为这个问题提供了新的解决方案。 相关文章: 开源模型应用落地-LangGraph101-探索…

调用链路传递隐式参数

在不修改方法签名与参数定义的情况下&#xff0c;可以通过 RpcContext 上的 setAttachment 和 getAttachment 在服务消费方和提供方之间进行参数的隐式传递。 隐式参数传递支持以下两个方向&#xff1a; 从消费方到提供方&#xff0c;也就是在请求发起时&#xff0c;在方法参数…