06_RBAC项目总结

news2024/11/25 7:06:54

RBAC项目总结

基于角色访问控制(RBAC:Role Based Access Control)

对于基本的增删改查

1.通过看接口文档要求这个接口使用什么方式发送请求,需要响应的数据的格式是什么

2.若请求的参数由其他对象或者数组组成的,就需要重新定义一个类来进行接收,后端接收的时候使用**@RequestBody**注解将传进来的数据进行封装

3.若相应的参数也是由对象或者数组组成的,也使用重新创建类的方式进行响应

4.若前端只传进来的一个id,后端使用**/{id}**接收

5.将增删改查的逻辑代码写在service里面,service在调用mapper中的方法

6.若存在关联表的增删改操作,则在service里面同时对两张表进行操作,若不进行删除就会出现很多脏数据,此时可以使用事务保证操作能同时进行,删除的时候先删除外键,再删除主表的字段,否则数据库会有异常

7.在mapper文件中如果需要传递多个参数给xml文件,需要使用**@Param**注解保证唯一性

8.mapper传进来的是一个对象的话,直接使用对象的属性获取,不可以使用对象.属性获取

9.当传过来的数据类型是数组/集合类型时,使用进行遍历

<!--修改员工角色关联,不可用-->
<update id="updateEmployeeRole">
    update employee_role set
    <foreach collection="roleIds" item="roleId" separator=",">
        (#{employee_id},#{roleId})
    </foreach>
    where employee_id= #{employee_id}
</update>

10.需要进行模糊查询或者过滤查询的时候使用where/if等动态sql

11.执行一对多查询的时候,使用association标签,执行多对一查询的时候用collection标签
在这里插入图片描述

分页查询

使用插件做分页,下载源码修改PageInfo,将不需要的属性使用**@JsonIgnore**注解让他不生效

PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
List<Employee> list = mapper.selectForList(qo);

将上一段贴在哪个方法就对那个进行分页

mysql使用foreach标签的弊端

里面权限分配的时候遍历使用了mysql自己的标签,若更换数据库就无法使用这个遍历的方法,但是效率较高

在业务层进行遍历就可以不用考虑数据库问题,但是效率较低

拦截器的设计

只有登录和获取验证码的路径是不用拦截的,其他路径都进行拦截

编写拦截器

实现HandlerInterceptor接口,要贴Controller注解

可以多次使用registry.addInterceptor()添加过滤的条件

注意事项

当用户没有进行登录的时候就进行其他操作是会进行拦截的

现在的过滤的条件有用户是否进行了登录用户是否有这个权限访问这个资源

此时通过id进行用户权限查询是没有的,值为null,此时进行查询的时候就会报numberFormatException

可以使用if来判断是否为null,为null就直接返回错误信息

注册/配置,这样才能生效

实现WebMvcConfigurer接口,要贴configuration注解

指向拦截的路径:addPathPatterns("/")**

排除的拦截路径:.excludePathPatterns(“/api/login”, “/api/code”);

接口统一异常处理

避免用户看到丑陋的报错页面

单独使用一个类进行统一异常处理

@ControllerAdvice
public class CommonControllerAdvice {

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public JsonResult handler(RuntimeException e){
        e.printStackTrace();
        return JsonResult.fail(500, e.getMessage());
    }

@ControllerAdvice:Controller的增强

可以使用断言的方式将异常抛出,在这里接收异常,将异常以Json的格式

怎样进行权限的加载

将所有的权限保存到数据库中

描述每个接口需要哪些权限(注解)

注解:元数据,用于来描述程序元素(类,方法,字段,形参…)的数据

现目前没有现成的注解可以使用,就自己定义注解

// 该注解能贴在哪
@Target(ElementType.METHOD)
// 该注解能保存到什么时期
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {

    String name();
    String expression();
}

在接口方法上贴上该注解,描述该方法需要什么权限才能访问

@RequiredPermission(name="员工添加和修改",expression="employee:saveOrUpdate")

从spring中找容器对象

@Autowired
private ApplicationContext ctx; // 容器对象
Map<String, Object> beansWithAnnotation = ctx.getBeansWithAnnotation(RestController.class);

找到Controller对象中所有的方法

Collection<Object> controllers = beansWithAnnotation.values();

遍历所有的方法,扫描所有Contrller中的@RequiredPermission注解

Method[] methods = controller.getClass().getDeclaredMethods();
  for (Method method : methods) {
                if(method.isAnnotationPresent(RequiredPermission.class)) {

如果有的话就获取注解中传递的参数

   RequiredPermission rp = method.getAnnotation(RequiredPermission.class);
String name = rp.name();
String expression = rp.expression()

查询所有的权限表达式,判断现在的权限表达式是否包含在集合对象中

List<Permission> permissions = mapper.selectAll();

如果不存在的话,就将参数封装到permission对象中,并保存到数据库中

Permission p = new Permission(null, name, expression);
if(!permissions.contains(p)) {
    mapper.insert(p);
}

默认比较的是地址,通过重写permission实体类中的equs和hashcode进行值的比较,不需要比较id就将id删除,

否则会在数据库中添加重复的数据

登录和验证码

1.使用工具类将code,uuid,code取到,并将code使用uuid作为key存储到redis中

2.可以将工具类里面获取的数据直接使用map集合的方式转成json格式发送给前端

3.验证码校验的时候可以使用equalsIgnoreCase方法来不区分大小写

4.前端将账户密码和验证码传到后端之后,将redis中的code和前端的code进行值比较

5.将账户密码拿到数据库中进行比较,如果能查到这个对象,就将这个对象以json格式存储到redis中

6.通过查询的员工数据,将里面的id取到,通过用户的id对三张表进行联查,查询用户所拥有的权限,将权限转成json存储到redis中

做注销

通过前端传进来的userId使用"req.getHeader(“userId”)"获取,使用该id将redis中的整个用户的数据删除

拦截器拦截的时候因为检查不到redis中有用户的数据就会退出登录

权限认证,拦截器中

用户发送一个请求的时候会访问一个资源,若这个资源的方法上面没有贴权限的注解或者该用户是管理员就直接放行

1.从redis中通过传进来的userId拿到整个用户的JSON,并转换成对象

2.判断是超管就直接放行

3.使用handler获取当前访问资源的权限,若方法上面没有权限的注解就直接放行

if(!method.isAnnotationPresent(RequiredPermission.class)) {
    return true;
}

4.有权限的话就获取Controller方法上的权限的表达式

RequiredPermission rp = method.getAnnotation(RequiredPermission.class);
String expression = rp.expression();

5.从redis中通过userId拿到这个用户所有的权限JSON字符串,并将其转换成集合的形式,将这个请求的权限表达式和集合中数据进行比较,若存在就放行

String expressionsJson = redisUtils.get("EMPLOYEE:PERMISSION:" + userId);
List<String> expressions = JSON.parseObject(expressionsJson, ArrayList.class);
if(expressions.contains(expression)) {
                return true; }

6.若不存在就进行拦截,并使用response.getWriter.print(“JSON字符串”)将错误信息进行响应

跨域问题

在这里插入图片描述

虽然配置了代理的请求方式,此时只能进行登录操作,不能对里面的数据进行操作

出现的原因就是:浏览器会发送一个预请求,看服务器是否支持跨域,若支持就发送真实数据,但是不会携带userId

出现预请求的时候就直接放行,使用全局配置,注意导包的时候使用Spring的

1.使用注解:@CrossOrigin(allowCredentials = “true”)

只是在每个接口上面都必须贴注解,操作非常的麻烦

2.使用全局配置

值需要写一个类就能满足需求

@Configuration
public class SpringMvcConfiguration implements WebMvcConfigurer {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
// 设置访问源地址
        config.addAllowedOrigin("*");
// 设置访问源请求头
        config.addAllowedHeader("*");
// 设置访问源请求方法
        config.addAllowedMethod("*");
// 有效期 1800秒
        config.setMaxAge(1800L);
// 添加映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
        return new CorsFilter(source);
    }
0秒
        config.setMaxAge(1800L);
// 添加映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
        return new CorsFilter(source);
    }

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

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

相关文章

(动态规划) 673. 最长递增子序列的个数 ——【Leetcode每日一题】

❓ 673. 最长递增子序列的个数 难度&#xff1a;中等 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列&#xff0c;分别是 [1, 3, 4, 7] 和[1,…

Leetcode-每日一题【328.奇偶链表】

题目 给定单链表的头节点 head &#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个节点的索引被认为是 奇数 &#xff0c; 第二个节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xff0c;偶数组和奇数组…

【Matlab】智能优化算法_樽海鞘群算法SSA

【Matlab】智能优化算法_樽海鞘群算法SSA 1.背景介绍2.数学模型2.1 提出的移动樽海鞘链的数学模型2.2 Swarm仿真2.3 单目标Salp Swarm算法&#xff08;SSA&#xff09; 3.算法流程图4.文件结构5.伪代码6.详细代码及注释6.1 func_plot.m6.2 Get_Functions_details.m6.3 initiali…

自学网络安全究竟该从何学起?

一、为什么选择网络安全&#xff1f; 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地&#xff0c;网络安全行业地位、薪资随之水涨船高。 未来3-5年&#xff0c;是安全行业的黄金发展期&#xff0c;提前踏入行…

八大数据结构分类

1、数组 数组是可以再内存中连续存储多个元素的结构&#xff0c;在内存中的分配也是连续的&#xff0c;数组中的元素通过数组下标进行访问&#xff0c;数组下标从0开始。例如下面这段代码就是将数组的第一个元素赋值为 1。 int[] data new int[100]&#xff1b;data[0] 1;…

大数据存储架构详解:数据仓库、数据集市、数据湖、数据网格、湖仓一体

前言 本文隶属于专栏《大数据理论体系》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见大数据理论体系 思维导图 数据仓库 数据仓库是一个面向主题的&…

Redis高可用——集群模式

Redis高可用——集群模式 一、Redis 群集模式二、集群的作用1.数据分区2.高可用 三、Redis集群的数据分片四、Redis集群的主从复制模型五、搭建Redis 群集模式1.创建每个redis节点的目录&#xff0c;复制需要的文件2.开启群集功能3.启动redis节点4.启动集群5.测试群集 一、Redi…

Leetcode 数据库刷题记录

https://leetcode-cn.com/problemset/database/ 题目都是leetcode 上的可以点击题目会有相应的链接 每道题后面都应相应的难度等级&#xff0c;如果没时间做的话 可以在leetcode 按出题频率刷题&#xff0c;答案仅供参考 175. 组合两个表 难度简单 SQL架构 表1: Person ---…

K210占用内存设定以及回收内存机制与方法

目录 占用内存设定 原有多行注释一键改为单行注释方法 内存回收&#xff1a;GC模块文档与教程 减少内存占用方法 多行注释测试 结果 单行注释测试 结果 畸变矫正测试 结果 死循环拍照内存测试 结果 占用内存设定 K210一次性将所有代码读取到内存。 K210有6MiB通用内…

SpringBoot 项目 整合Redis

一、java连接单机redis&#x1f349; 1.创建一个普通的maven工程&#x1f95d; 2.引入依赖&#x1f95d; <dependencies><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.8.0</version&…

【Docker镜像部署】镜像方式部署登录服务验证码无法刷出问题

背景 auth服务本地部署&#xff0c;验证码正常显示。但是一旦镜像部署则会报错。 Dockerfile文件如下 FROM daocloud.io/library/java:8-jre-alpine MAINTAINER zzjs # 时区问题 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo Asia/Shanghai >/e…

第四章 数组

前言 学习方法 可以多看几遍视频把上课的代码&#xff0c;自己加加注释&#xff0c;在自己写之前&#xff0c;可以画一个流程图照着流程图把代码自己实现一遍 不要怀疑自己&#xff0c;不要遇到困难就觉得自己不行&#xff0c;遇到困难就解决困难&#xff0c;编程初学者都是…

php代码审计8之SSRF

文章目录 1、关注函数2、SSRF支持的协议2.1、http/https&#xff1a;2.2、file&#xff1a;2.3、dict&#xff1a;2.4、gopher&#xff1a;2.5、ftp/ftps&#xff1a;2.6、tftp&#xff1a;2.7、imap/imaps/pop3/smtp/smtps&#xff1a;2.8、telnet&#xff1a; 3、绕过3.1、读…

flask.send_file实现文件下载、文件传输和二进制流传输

文章目录 flask.send_file函数常用参数描述url直接下载文件flask.send_file文件传输本地文件传输二进制流传输 在使用flask框架时&#xff0c;我们有时需要向前端传输文件。或者需要用户访问一个url时直接下载文件。这时可以使用flask.send_file()函数来实现相关的操作。 flask…

HarmonyOS学习路之开发篇—设备管理(控制类小器件)

控制类小器件开发概述 基本概念 控制类小器件指的是设备上的LED灯和振动器。其中&#xff0c;LED灯主要用作指示&#xff08;如充电状态&#xff09;、闪烁功能&#xff08;如三色灯&#xff09;等&#xff1b;振动器主要用于闹钟、开关机振动、来电振动等场景。 运作机制 控…

Spring Boot 中的 @RefreshScope 注解是什么,原理,如何使用

Spring Boot 中的 RefreshScope 注解是什么&#xff0c;原理&#xff0c;如何使用 在 Spring Boot 中&#xff0c;RefreshScope 注解是一个非常有用的注解。它可以让 Spring Boot 应用程序在运行时重新加载配置。这意味着您可以在不停止和重新启动应用程序的情况下更改配置。在…

大宇无限:一家中国初创企业的出海之旅

如果一家中国企业想要拓展海外市场&#xff0c;那么应该如何开启自己的出海之旅&#xff1f; 大宇无限的出海之路 作为一家互联网科技领域的初创企业&#xff0c;大宇无限的出海之旅对那些想要拓展海外业务的中国企业来说&#xff0c;无疑有着极佳的学习价值和借鉴意义。 “大宇…

WebAssembly:让Istio变得更强大

1 Wasm为Envoy带来新的扩展性 Envoy是一个高性能、可编程的L3/L4和L7网络代理&#xff0c;许多服务网格和网关都采用Envoy作为数据面。 Envoy通过监听器&#xff08;Listener&#xff09;捕获网络数据包&#xff0c;根据数据包的内容匹配某个过滤器链&#xff08;Filter Chai…

工作方法 - 戒定慧

风动、旗动&#xff0c;以及两种冰球棍的摆法 戒。就是戒律&#xff0c;知道边界。 在一个公司的工作中&#xff0c;就是知道我们的核心目标&#xff0c;核心资源&#xff0c;核心用户都是什么。 不是什么热闹都去凑&#xff0c;没有资源去做的事情也去做&#xff0c;非核心用…

记录--多行标签超出展开折叠功能

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 记录分享每一个日常开发项目中的实用小知识&#xff0c;不整那些虚头巴脑的框架理论与原理&#xff0c;之前分享过抽奖功能、签字功能等&#xff0c;有兴趣的可以看看本人以前的分享。  今天要分…