过滤器Filter和拦截器Interceptor实现登录校验

一.过滤器

  • Filter过滤器可以把对资源的请求拦截下来,从而实现一些登录验证的功能

1.Filter的快速入门

  • 1.定义Filter:定义一个类,实现Filter接口,并重写其所有方法。
  • 2.配置
public class dofilter implements Filter {@Override //初始化只执行一次public void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}@Override  //拦截操作public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("拦截操作执行");//放行前逻辑System.out.println("放行前逻辑");// 放行 到达下一个filter(如果有)或者执行资源方法filterChain.doFilter(servletRequest,servletResponse);//获取资源后返回System.out.println("获取资源后返回");}@Overridepublic void destroy() {//销毁只执行一次Filter.super.destroy();}
}

Filter类上加@WebFilter注解,配置拦截资源的路径。

3fbc488fe35b49b9b20be64056d9c209.png

启动类上加@ServletComponentScan开启Servlet组件支持。

74c604eea3964035837966f43ba6bbf7.png

Filter可以根据需求,配置不同的拦截资源路径:

4047693a7f0946deb8b85e58b0a67e37.png

过滤器链

  • 介绍:一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链

优先级是按照过滤器名字首字母顺序

2.JWT和过滤器Filter实现登录校验

  1. 获取请求url
  2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行
  3. 获取请求头中的令牌(token)
  4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)
  5. 解析token,如果解析失败,返回错误结果(未登录)
  6. 放行
package it.com.springbootmybatisprimary.filter;import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import it.com.springbootmybatisprimary.pojo.Result;
import it.com.springbootmybatisprimary.utils.AliOSSUtils;
import it.com.springbootmybatisprimary.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@WebFilter("/*")
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("拦截到请求");HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String url=request.getRequestURI().toString();//获取请求urllog.info("url {}",url);if(url.contains("login")){//1.url包含login的话放行//包含login执行放行操作并returnlog.info("放行");filterChain.doFilter(servletRequest,servletResponse);return;//获取web资源后直接返回}//2.获取jwtString jwt = request.getHeader("token");//3.检查jst令牌不为空if(!StringUtils.hasLength(jwt)){//返回错误信息Result error = Result.error("NO_LOGIN");log.info("jwt令牌不存在");//转化为json格式数据 利用fastjsonString s= JSONObject.toJSONString(error);response.getWriter().write(s);return;}//4.检查jwt令牌合法try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("解析失败 返回报错");Result error = Result.error("NO_LOGIN");//转化为json格式数据String s= JSONObject.toJSONString(error);response.getWriter().write(s);return;}//5.放行log.info("合法 放行");filterChain.doFilter(request,response);}
}

Postman测试

1.含有login请求

30f3c7f2e3354beaa8fe2aebc473bc9f.png

2.不含login请求

1593ee30c8d64e58b82bbc03ac42d940.png

9990e00548224d4ea992013e8f4b1146.png

3.请求头包含jwt测试

首先获取JWT令牌

然后emps请求携带JWT令牌测试

e76aad0e4f9e4f2085ed0a5d1c0d7fe6.png

控制台

0772a58385a94d3f8833ab80728f5b50.png

输入错误JWT 校验失败返回报错

87ba63bb1eed498280a72bc80b06e9f2.png

c135beb265dd4eb8bddad401b4700766.png

二.拦截器

什么是拦截器?

是一种动态拦截方法调用的机制,类似于过滤器。
拦截器的作用:

拦截请求,在指定方法调用前后,根据业务需要执行预先设定的代码。

1.拦截器Interceptor入门

1.定义类实现HandleInterceptor接口

5b418176b6944bb89766fbb6c4bda0c0.png

2.定义配置类实现WebMvcConfigurer

0d760dc98b54462d98037458f40f2a77.png

3.postman测试

1.放行的情况

prehandle返回true 表示放行,执行资源方法完毕后,执行posthandle和aftercompletion

cd1e7c17eaac477cb500bc4e4c1113e1.png

e0550411a46145118b5d936317533880.png

2.不放行的情况

prehandle返回false表示不放行一直被拦截

edfb84d92a474be290d8f6e335aeb159.png

d80fd9d9225241bb8fdacffd5fc422b5.png

2.拦截路径

在拦截器中除了可以设置/**拦截所有资源外,还有一些常见拦截路径设置:

拦截路径

含义

举例

/*

一级路径

能匹配/depts,/emps,/login,不能匹配 /depts/1

/**

任意级路径

能匹配/depts,/depts/1,/depts/1/2

/depts/*

/depts下的一级路径

能匹配/depts/1,不能匹配/depts/1/2,/depts

/depts/**

/depts下的任意级路径

能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1

 

  • 在controller当中的方法执行完毕之后,再回过来执行

postHandle()这个方法以及afterCompletion() 方法,然后再返回给DispatcherServlet,最终再来执行过滤器当中放行后的这一部分逻辑的逻辑。执行完毕之后,最终给浏览器响应数据。

3.拦截器与过滤器执行时机

  • 当我们打开浏览器来访问部署在web服务器当中的web应用时,此时我们所定义的过滤器会拦截到这次请求。拦截到这次请求之后,它会先执行放行前的逻辑,然后再执行放行操作。而由于我们当前是基于springboot开发的,所以放行之后是进入到了spring的环境当中,也就是要来访问我们所定义的controller当中的接口方法。
  • Tomcat并不识别所编写的Controller程序,但是它识别Servlet程序,所以在Spring的Web环境中提供了一个非常核心的Servlet:DispatcherServlet(前端控制器),所有请求都会先进行到DispatcherServlet,再将请求转给Controller。
  • 当我们定义了拦截器后,会在执行Controller的方法之前,请求被拦截器拦截住。执行

e30070a0ebd54260a2eb9fefdf3a36b0.png

拦截器与过滤器的区别:

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
  • 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。

postman测试控制台输出日志

c7579243a4984ba9b58f14917f9715f5.png

2.拦截器InterCeptor实现登录校验功能

在放行前进行登录校验所以在prehandle函数进行

与过滤器实现登录校验逻辑一致,直接复制修改一下

放行操作改为return true 不放行操作改为return false

类型就是Http类型不用强转

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("执行preHandle");//访问资源前执行 return true表示放行 false表示拦截/*  System.out.println("filter拦截到请求");*///强转 能够调HttpServletRequest和HttpServletResponse接口中特有的方法和属性,这些方法和属性在更通用的//ServletRequest和ServletResponse接口中并不存在。例如要获取请求的URL/getRequestURI())、查询参数(//getParameter())、请求头(getHeader())等String url = request.getRequestURI().toString();//获取请求urllog.info("url {}", url);if (url.contains("login")) {//1.url包含login的话放行//包含login执行放行操作并return/*   log.info("filter放行");*/return true;/* System.out.println("filter放行后");*/}//2.获取请求jwtString jwt = request.getHeader("token");//获取token携带的jwt//3.检查jst令牌不为空if (!StringUtils.hasLength(jwt)) {//返回错误信息Result error = Result.error("NO_LOGIN");log.info("jwt令牌不存在");//转化为json格式数据 利用fastjsonString s = JSONObject.toJSONString(error);response.getWriter().write(s);return true;}//4.检查jwt令牌合法try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("解析失败 返回报错");Result error = Result.error("NO_LOGIN");//转化为json格式数据String s = JSONObject.toJSONString(error);response.getWriter().write(s);//写入响应体(getWriter().write())return false;}//5.放行log.info("合法 放行");/*filterChain.doFilter(request, response);//继续过滤器链*/return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("执行postHandle");//资源方法执行后执行}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("执行afterCompletion");//视图渲染后执行}
}

postman测试

58ec3c64953a430195bde99fa35e16e0.png

aa078093c4be4b69b85e89945d14c469.png

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手撸XXL-JOB(三)——本地定时任务管理平台

引言 在XXL-JOB中,有一个xxl-job-admin项目,这个就相当于定时任务的调度平台,我们参考XXL-JOB,也添加这么一个调度平台,由于篇幅有限,我们先实现一个本地的定时任务调度平台,至于如何调用远程的…

(2024,MambaOut,Mamba 适合长序列,区分指标,不适合分类,适合检测和分割)视觉真的需要 Mamba 吗?

MambaOut: Do We Really Need Mamba for Vision? 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 1. 简介 3. 概念讨论 3.1 Mamba 适合哪些任务? 3.2 视觉识别任…

接口测试基础

1、接口测试 接口:系统之间数据交互的通道。 硬件接口软件接口 接口测试:基于不同的输入参数,校验接口响应数据与预期数据是否一致。 接口地址 接口参数 2. 为什么要学接口测试? 提前介入测试、尽早发现问题 3、接口测试学什…

十二生肖Midjourney绘画大挑战:释放你的创意火花

随着AI艺术逐渐进入大众视野,使用Midjourney绘制十二生肖不仅能够激发我们的想象力,还能让我们与传统文化进行一场新式的对话。在这里,我们会逐一提供给你创意满满的绘画提示词,让你的作品别具一格。而且,我们还精选了…

2024年金属非金属矿山(露天矿山)安全管理人员证考试题库及金属非金属矿山(露天矿山)安全管理人员试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2024年金属非金属矿山(露天矿山)安全管理人员证考试题库及金属非金属矿山(露天矿山)安全管理人员试题解析是安全生产模拟考试一点通结合(安监局)…

【C++】每日一题 17 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 可以使用回溯法来解决这个问题。首先定义一个映射关系将数字与字母对应起来…

嵌入式Linux:编译和使用Protobuf库

目录 1、开发环境和工具 2、安装和编译Protobuf、Protobuf-C库 3、编写和编译proto文件 4、修改makefile文件 5、测试示例 6、参考资料 Protobuf(Protocol Buffers)是由 Google 开发的一种轻量级、高效的结构化数据序列化方式,用于在不同应用…

内联函数+auto关键字(C++11)+指针空指针nullptr(C++11)

内联函数auto关键字(C11)指针空指针nullptr(C11)详解 内联函数概念特性 auto关键字(C11)auto简介auto的使用细则auto不能推导的场景 基于范围的for循环(C11)范围for的语法范围for的使用条件 指针空指针null…

算法-卡尔曼滤波之卡尔曼滤波的第二个方程:预测方程(状态外推方程)

在上一节中,使用了静态模型,我们推导出了卡尔曼滤波的状态更新方程,但是在实际情况下,系统都是动态,预测阶段,前后时刻的状态是改变的,此时我们引入预测方程,也叫状态外推方程&#…

[动画详解]LeetCode151.翻转字符串里的单词

💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到动画详解LeetCode算法系列 用通俗易懂的动画让算法题不再神秘 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低成…

go语言基础1

1.token token是构成源程序的基本不可在分割单元。编译器编译源程序的第一步就是将源程序分割为一个个独立的token,这个过程就是词法分析。Go语言的token可以分为关键字、标识符、操作符、分隔符和字面常量等,如图所示: Go token分隔符有两类…

c#多态性的应用

设计一个电脑游戏,游戏中有猪、牛、兔子、青蛙、鸭子等动物,这些动 物都继承于Vertebrata 类(脊椎动物类),Vertebrata类有一个抽象方法Display(),每个动 物都从Vertebrata 类那里继承并重写了Display()方法…