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


    一.过滤器

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

    1.Filter的快速入门

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

    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. 放行
    1. package it.com.springbootmybatisprimary.filter;
    2. import com.alibaba.fastjson.JSONObject;
    3. import com.github.pagehelper.util.StringUtil;
    4. import it.com.springbootmybatisprimary.pojo.Result;
    5. import it.com.springbootmybatisprimary.utils.AliOSSUtils;
    6. import it.com.springbootmybatisprimary.utils.JwtUtils;
    7. import lombok.extern.slf4j.Slf4j;
    8. import netscape.javascript.JSObject;
    9. import org.springframework.util.StringUtils;
    10. import javax.servlet.*;
    11. import javax.servlet.annotation.WebFilter;
    12. import javax.servlet.http.HttpServletRequest;
    13. import javax.servlet.http.HttpServletResponse;
    14. import java.io.IOException;
    15. @Slf4j
    16. @WebFilter("/*")
    17. public class LoginFilter implements Filter {
    18. @Override
    19. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    20. System.out.println("拦截到请求");
    21. HttpServletRequest request = (HttpServletRequest) servletRequest;
    22. HttpServletResponse response = (HttpServletResponse) servletResponse;
    23. String url=request.getRequestURI().toString();//获取请求url
    24. log.info("url {}",url);
    25. if(url.contains("login")){//1.url包含login的话放行
    26. //包含login执行放行操作并return
    27. log.info("放行");
    28. filterChain.doFilter(servletRequest,servletResponse);
    29. return;//获取web资源后直接返回
    30. }
    31. //2.获取jwt
    32. String jwt = request.getHeader("token");
    33. //3.检查jst令牌不为空
    34. if(!StringUtils.hasLength(jwt)){//返回错误信息
    35. Result error = Result.error("NO_LOGIN");
    36. log.info("jwt令牌不存在");
    37. //转化为json格式数据 利用fastjson
    38. String s= JSONObject.toJSONString(error);
    39. response.getWriter().write(s);
    40. return;
    41. }
    42. //4.检查jwt令牌合法
    43. try {
    44. JwtUtils.parseJWT(jwt);
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. log.info("解析失败 返回报错");
    48. Result error = Result.error("NO_LOGIN");
    49. //转化为json格式数据
    50. String s= JSONObject.toJSONString(error);
    51. response.getWriter().write(s);
    52. return;
    53. }
    54. //5.放行
    55. log.info("合法 放行");
    56. filterChain.doFilter(request,response);
    57. }
    58. }

    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类型不用强转

    1. @Slf4j
    2. @Component
    3. public class LoginCheckInterceptor implements HandlerInterceptor {
    4. @Override
    5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    6. System.out.println("执行preHandle");//访问资源前执行 return true表示放行 false表示拦截
    7. /* System.out.println("filter拦截到请求");*/
    8. //强转 能够调HttpServletRequest和HttpServletResponse接口中特有的方法和属性,这些方法和属性在更通用的
    9. //ServletRequest和ServletResponse接口中并不存在。例如要获取请求的URL/getRequestURI())、查询参数(
    10. //getParameter())、请求头(getHeader())等
    11. String url = request.getRequestURI().toString();//获取请求url
    12. log.info("url {}", url);
    13. if (url.contains("login")) {//1.url包含login的话放行
    14. //包含login执行放行操作并return
    15. /* log.info("filter放行");*/
    16. return true;
    17. /* System.out.println("filter放行后");*/
    18. }
    19. //2.获取请求jwt
    20. String jwt = request.getHeader("token");//获取token携带的jwt
    21. //3.检查jst令牌不为空
    22. if (!StringUtils.hasLength(jwt)) {//返回错误信息
    23. Result error = Result.error("NO_LOGIN");
    24. log.info("jwt令牌不存在");
    25. //转化为json格式数据 利用fastjson
    26. String s = JSONObject.toJSONString(error);
    27. response.getWriter().write(s);
    28. return true;
    29. }
    30. //4.检查jwt令牌合法
    31. try {
    32. JwtUtils.parseJWT(jwt);
    33. } catch (Exception e) {
    34. e.printStackTrace();
    35. log.info("解析失败 返回报错");
    36. Result error = Result.error("NO_LOGIN");
    37. //转化为json格式数据
    38. String s = JSONObject.toJSONString(error);
    39. response.getWriter().write(s);//写入响应体(getWriter().write())
    40. return false;
    41. }
    42. //5.放行
    43. log.info("合法 放行");
    44. /*filterChain.doFilter(request, response);//继续过滤器链*/
    45. return true;
    46. }
    47. @Override
    48. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    49. System.out.println("执行postHandle");//资源方法执行后执行
    50. }
    51. @Override
    52. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    53. System.out.println("执行afterCompletion");//视图渲染后执行
    54. }
    55. }

    postman测试

    58ec3c64953a430195bde99fa35e16e0.png

    aa078093c4be4b69b85e89945d14c469.png

     

  • 相关阅读:
    Gbase数据库
    SpringMVC环境搭建——配置文件版,配置文件+部分注解版
    【web-攻击用户】(9.5)同源策略:与浏览器扩展、HTML5、通过代理服务应用程序跨域
    Sql查询语句
    RK3568平台开发系列讲解(图像篇)JPEG图像处理
    关于“No loop matching the specified signature and casting was found for ufunc lstsq_n”问题的解决
    应急响应笔记
    小米、Vivo、Oppo后台弹出界面权限检测
    【高级rabbitmq】
    护眼台灯哪个牌子最好?消费者信赖之选护眼灯十大品牌推荐
  • 原文地址:https://blog.csdn.net/fjf_666/article/details/138873112