Springboot 拦截器,拦截所有请求,判断是否登录,验证权限
Java的三大器
拦截器的作用
Java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。
功能:可以进行权限验证,审计日志等。
代码实现
拦截器配置类
package com.thk.Interceptor;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 拦截器的属性配置**/
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {/*** 重写addCorsMappings()解决跨域问题* 配置:允许http请求进行跨域访问** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {//指哪些接口URL需要增加跨域设置registry.addMapping("/**")//.allowedOrigins("*")//指的是前端哪些域名被允许跨域.allowedOriginPatterns("*")//需要带cookie等凭证时,设置为true,就会把cookie的相关信息带上.allowCredentials(true)//指的是允许哪些方法.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")//cookie的失效时间,单位为秒(s),若设置为-1,则关闭浏览器就失效.maxAge(3600);}/*** 重写addInterceptors()实现拦截器* 配置:要拦截的路径以及不拦截的路径** @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册Interceptor拦截器(Interceptor这个类是我们自己写的拦截器类)InterceptorRegistration registration = registry.addInterceptor(new Interceptor());//addPathPatterns()方法添加需要拦截的路径//所有路径都被拦截registration.addPathPatterns("/**");//excludePathPatterns()方法添加不拦截的路径//添加不拦截路径registration.excludePathPatterns(//登录"/login",//退出登录"/loginOut",//获取验证码"/getCode",//发送短信"/sendshortMessage",//重置账号"/unsealaccount",//文件上传"/uploadImg",//html静态资源"/**/*.html",//js静态资源"/**/*.js",//css静态资源"/**/*.css");}
}
拦截器实现类
package com.thk.Interceptor;import com.thk.controller.base.BaseController;
import com.thk.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 拦截器*/
public class Interceptor extends BaseController implements HandlerInterceptor {@Autowiredprivate RedisUtil redisUtil;/*** 在请求处理之前进行调用(Controller方法调用之前)*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {try {//判断是否登录boolean verifyPermissions = verifyPermissions(request);//判断是否有权限boolean competence = competence(request);if (verifyPermissions && competence) {return true;}//这里设置拦截以后重定向的页面,一般设置为登陆页面地址response.sendRedirect(request.getContextPath() + "/error.html");} catch (Exception e) {e.printStackTrace();}return true;//如果设置为false时,被请求时,拦截器执行到此处将不会继续操作//如果设置为true时,请求将会继续执行后面的操作}
}
判断是否登录
1.从请求头中获取token
2.通过token从redis中获取当前登录对象(object)
3.判断object是否为空,如果为空就是未登录或者登录时间过期
/*** 验证是否登录** @param request* @return*/public boolean verifyPermissions(HttpServletRequest request) {String token = request.getHeader(Constant.TOKEN);Object o = redisUtil.get(token);if (o != null) {return true;}return false;}
判断是否有权限
1.从请求头中获取token
2.通过token从redis中获取当前登录对象(object)
3.通过对象查询数据库是否存在当前对象
4.获取登录对象的登录名 判断是否是(admin或者总经理)这两个账号拥有最高权限
5.判断是否被授权,(获取临时授权时设置的开始时间,结束时间,当前时间),
获取这个三个时间的时间戳,判断当前时间是否在开始时间和结束时间之间
如果开始时间和结束时间为空的话表示当前登录对象未被临时授权,会执行后面的 4,5,6,
如果有时间,但是当前时间不在这个时间段也会执行 4,5,6
如果有时间,并且当前时间在这个时间段之中,就会直接返回true
6.从请求头中获取当前接口的地址,
7.通过当前登录对象的id查询权限
8.判断当前登录对象的权限中是否包含当前接口的地址,如果包含,允许当前登录对象访问,如果不包含,则不允许当前登录人访问
/*** 判断是否有权限** @param request* @return*/public boolean competence(HttpServletRequest request) {//获取当前登录对象的全部信息People people = peopleMapper.selectById(getUserId(request.getHeader(Constant.TOKEN)));//管理员拥有全部权限if (Constant.SUPER_ADMIN.equals(people.getUserName())) {return true;}//判断是否被授权//防止空指针if (people.getStartDate() != null && people.getEndDate() != null) {if (dateUtils.ifDate(people.getStartDate(), people.getEndDate(), new Date())) {return true;}}//从请求头中获取的地址String requestURI = request.getRequestURI();//通过角色id查询当前登陆对象的所有权限List<Power> list = powerMapper.selectUrl(people.getRoleid());ArrayList<String> stringList = new ArrayList<>();if (!StringUtils.isEmpty(list)) {list.forEach(r -> {stringList.add(r.getUrl());});return lsitUtils.ifcontainString(stringList, requestURI);}return false;}
测试
1.获取验证码
2.登录获取token
(eyJhbGciOiJIUzI1NiJ9eyJqdGkiOiIyMDFlNmY0MS1jM2NhLTRmODItYjAxNC01NWY3ZTU5ZmNkMzgiLCJpYXQiOjE2NTIwNzE1MTMsInN1YiI6InRoayIsImlzcyI6InN0YWZmIiwiZXhwIjoxNjUyMDczMzEzfQunBHUktwyuKpT6D0NDObrPmYGjQ_yU8-lNJ0NbAwHMI)
3.查询全部用户
总结:
避坑问题:
在拦截器中@autowired注入工具类,或者其他service,mapper会导致空指针异常
解决方案:
原因:
因为拦截器是在spring创建controller之前运行的,这时候这些controller,service,实体类等等这些东西spring并没有去创建,所以会注入失败,并且报空指针异常
解决方法
将这个拦截器类也交给spring来进行管理
1.写一个@bean 来创建拦截器类
2.在addInterceptors 方法引用中调用这个bean
3.修改后的代码
package com.thk.Interceptor;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 拦截器的属性配置**/
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {/*** 把Interceptor这个实现类交给spring进行管理-------避坑!!!* @return*/@BeanInterceptor getAdminInterceptor(){return new Interceptor();}/*** 重写addCorsMappings()解决跨域问题* 配置:允许http请求进行跨域访问** @param registry* @Author 有梦想的肥宅*/@Overridepublic void addCorsMappings(CorsRegistry registry) {//指哪些接口URL需要增加跨域设置registry.addMapping("/**")//.allowedOrigins("*")//指的是前端哪些域名被允许跨域.allowedOriginPatterns("*")//需要带cookie等凭证时,设置为true,就会把cookie的相关信息带上.allowCredentials(true)//指的是允许哪些方法.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")//cookie的失效时间,单位为秒(s),若设置为-1,则关闭浏览器就失效.maxAge(3600);}/*** 重写addInterceptors()实现拦截器* 配置:要拦截的路径以及不拦截的路径** @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册Interceptor拦截器(Interceptor这个类是我们自己写的拦截器类)InterceptorRegistration registration = registry.addInterceptor(getAdminInterceptor());//addPathPatterns()方法添加需要拦截的路径//所有路径都被拦截registration.addPathPatterns("/**");//excludePathPatterns()方法添加不拦截的路径//添加不拦截路径registration.excludePathPatterns(//登录"/login",//退出登录"/loginOut",//获取验证码"/getCode",//发送短信"/sendshortMessage",//重置账号"/unsealaccount",//文件上传"/uploadImg",//html静态资源"/**/*.html",//js静态资源"/**/*.js",//css静态资源"/**/*.css");}
}
4.问题解决
Springboot 拦截器,拦截所有请求,判断是否登录,验证权限相关推荐
- java 判断请求为 ajax请求_Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求...
Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java 判断请求是不是ajax请求,Java判断是否为ajax请求 >>>>>> ...
- Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求
Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,java 判断请求是不是ajax请求 Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java 判断 ...
- php 请求拦截,解决拦截器对ajax请求的拦截实例详解
解决拦截器对ajax请求的的拦截 拦截器配置:public boolean preHandle(HttpServletRequest request, HttpServletResponse resp ...
- 修改拦截器里的请求头_OkHttp4 源码分析(1) 请求流程分析
square/okhttpgithub.com 本文基于OkHttp4.7.1分析 同步请求示例代码 OkHttpClient client = new OkHttpClient.Builder() ...
- spring拦截器 拦截和排除接口冲突
以下为springboot案例: 场景: 某个规则下的绝大部分接口路径不需要经过拦截器, 但其中的某几个接口又需要经过拦截器. 例如: "/api/register/**" 模式 ...
- java url 拦截_Spring mvc设置某些url不被interceptor拦截器拦截的方法
我们的Java类继承HandlerInterceptorAdapter类之后,实现里面的preHandle与postHandle方法,默认情况下所有的url都会被spring mvc拦截器所拦截,因为 ...
- axios config里自定义属性,使用拦截器拦截,无法拿到自定义属性问题
axios config里自定义属性,使用拦截器拦截,无法拿到自定义属性问题 最新版本axios限制了键,对键值做了白名单处理. 解决思路: 修改源码中的内容,添加一个键来报错额外属性. 或者:使用老 ...
- 在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案
在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 参考文章: (1)在JSP中常见问题,防止SpringMVC拦截器拦截js等静态资源文件的解决方案 (2)https: ...
- 【项目经验】拦截器拦截入参出参
文章目录 拦截器拦截入参出参 入参 出参 拦截器拦截入参出参 入参 @Overridepublic boolean preHandle(HttpServletRequest request, Http ...
- springboot 自定义拦截器 防止恶意请求
该例子需要用到 redis 在applocation.properties中加入redis的配置信息 server.port=8081# Redis数据库索引(默认为0) spring.redis.d ...
最新文章
- RocketMQ Apache顶级项目之路
- 围观一下tp的游戏保护 一
- linux下程序如何实现单实例运行
- 如何在vs2010中修改栈的大小
- 设计模式(三):单例模式
- Mybatis 与java 类型 对应表
- python读取中文txt操作 转化为拼音
- ffmpeg 使用小记
- python 1加到100的三种方法
- 什么是webservice
- Gitlab 登录报422错误,账号密码是对的?
- 关于ajax同步状态及sucess,complete的顺序的理解
- 【开源小软件 】Bing每日壁纸 V1.2.1
- Microsoft 365 E5 开发者扩容到5T
- java根据提供word模板导出word文档
- C# linq的学习及使用
- ALE重新授权,简译笔记
- 剑麻的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- java查询ftp路径下所有文件名字
- 将Java中的内容直接存储为二进制文件