登录-10.Filter-登录校验过滤器

打印 上一主题 下一主题

主题 889|帖子 889|积分 2667

一.登录校验过滤器的实现思绪


我们要实现登录校验过滤器,就要首先明白登录校验过滤器的实现思绪。登录校验过滤器是用来实现登录校验的。那么首先思索第一个题目,全部的请求都必要校验吗?

答案是否定的,由于login请求就不必要过滤器校验,由于登录请求本身就不携带JWT令牌,登录的目的就是为了获取JWT令牌用于后续的校验,如果login请求也必要校验的话,那么将没有用户可以登录成功进而访问服务器中的资源。因此登录请求"/login"是不必要校验的,要直接放行。

下面思索第二个题目,当我们拦截到请求后,什么情况下才可以放行?答案是当拦截到的请求中的请求头header所携带的JWT令牌存在且有效时才气够放行执行业务操作,只要不存在大概无效,那么就不会放行执行操作,从而跳转到登录页面。

基于以上分析,我们绘制出登录校验过滤器的流程分析图。


二.代码实现

  1. package com.gjw.filter;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.gjw.pojo.Result;
  4. import com.gjw.util.JwtUtils;
  5. import jakarta.servlet.*;
  6. import jakarta.servlet.annotation.WebFilter;
  7. import jakarta.servlet.http.HttpServletRequest;
  8. import jakarta.servlet.http.HttpServletResponse;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.util.StringUtils;
  11. import java.io.IOException;
  12. @Slf4j
  13. @WebFilter(urlPatterns = "/*")
  14. public class LoginCheckFilter implements Filter {
  15.     @Override
  16.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  17.         HttpServletRequest request = (HttpServletRequest) servletRequest;
  18.         HttpServletResponse response = (HttpServletResponse) servletResponse;
  19.         // 1.获取请求的url
  20.         String requestURL = request.getRequestURL().toString();
  21.         log.info("获取请求的URL:{}",requestURL);
  22.         // 2.判断url中是否包含"login"
  23.         if (requestURL.contains("login")) {
  24.             log.info("登录操作,直接放行......");
  25.             // 如果包含,直接放行
  26.             filterChain.doFilter(servletRequest,servletResponse);
  27.             return;
  28.         }
  29.         // 3.不包含则获取JWT令牌并检验
  30.         String jwt = request.getHeader("token");
  31.         // 4.检验JWT令牌是否存在,如果不存在,则返回错误结果(未登录)
  32.         if(!StringUtils.hasLength(jwt)) {   // jwt不存在或者为null,返回false
  33.             log.info("请求头token为空,返回登录页面......");
  34.             Result error = Result.error("NOT_LOGIN");
  35.             String notLogin = JSONObject.toJSONString(error);// 没有RestController注解,无法将直接return的数据以JSON格式返回,需要强转为JSON  手动转换:对象----->JSON格式的数据
  36.             response.getWriter().write(notLogin);  // 通过response对象返回JSON格式的数据
  37.             return;
  38.         }
  39.         // 5.如果存在,校验JWT令牌是否正确,如果解析失败,则返回错误结果(未登录)
  40.         try {
  41.             JwtUtils.parseJWT(jwt);     // 解析成功放行
  42.         } catch (Exception e) {     // 失败捕获异常
  43.             e.printStackTrace();
  44.             log.info("解析失败,返回未登录的错误信息......");
  45.             Result error = Result.error("NOT_LOGIN");
  46.             String notLogin = JSONObject.toJSONString(error);// 没有RestController注解,无法将直接return的数据以JSON格式返回,需要强转为JSON  手动转换:对象----->JSON格式的数据
  47.             response.getWriter().write(notLogin);  // 通过response对象返回JSON格式的数据
  48.             return;
  49.         }
  50.         // 6.JWT令牌存在且解析成功,放行
  51.         log.info("令牌合法,放行。");
  52.         filterChain.doFilter(servletRequest,servletResponse);
  53.     }
  54. }
复制代码
 1.获取请求的url

我们首先要获取到请求的url地址,为了获取请求的url地址,必要将ServletRequest和ServletResponse强转为HttpServletRequest和HttpServletResponse。强转后通过调用HttpServletRequest的getRequestURL()方法获取URL路径。

2.判定url中是否包罗"login"

获取到URL路径后,接下来我们首先要判定路径中是否包罗关键字"login",如果包罗,那么证实该请求是一个登录请求,直接放行即可。使用doFilter方法将HttpServletRequest和HttpServletResponse对象传递进去。然后使用return直接结束该方法。

3.不包罗则获取JWT令牌并检验

如果不包罗关键字"login",那么证实该请求不是一个登录请求,那么就举行下面两部判定:

首先获取该请求中请求头header的token字段,从而获取到JWT令牌,然后判定JWT令牌是否存在。使用request.getHeader("token")来获取JWT令牌的字符串。

4.检验JWT令牌是否存在,如果不存在,则返回错误结果(未登录)

如果不存在,纵然用StringUtils工具类的hasLength方法(空串大概null返回false,有值返回true)判定结果为空串大概null,取反后(!)为true。

我们与前端约定好的

那么调用Result结果封装类中的error方法,传递一个"NOT_LOGIN"。但是我们要响应给前端的是一个JSON格式的数据,那么如何将这个Result对象转为JSON再响应给前端呢?在controller当中我们可以使用注解@RestController,会主动将方法的返回值转为JSON格式的数据返回回去,但是现在是在Filter过滤器当中,因此要手动转换。我们可以使用alibaba提供的fastJSON的工具包,首先引入依靠


  1. <dependency>
  2.             <groupId>com.alibaba</groupId>
  3.             <artifactId>fastjson</artifactId>
  4.             <version>2.0.52</version>
  5. </dependency>
复制代码
然后使用JSONObject将对象转为JSON格式的字符串,然后我们将该字符串相应给浏览器。通过响应对象response调用其中的getWriter()获取一个输出流,再调用内里的writer()方法将要响应未登岸的数据notLogin传递给前端。然后直接结束方法,跳转到登录页面。

5.如果存在,校验JWT令牌是否正确,如果分析失败,则返回错误结果(未登录)

如果令牌存在,那么首先校验令牌的合法性,如果合法,直接放行。如果不合法,那么和上面的代码逻辑一样。因此我们必要使用try/catch捕获非常信息,如果未捕获到非常,那么直接放行;如果捕获到非常,那么执行和上面一样的代码逻辑。

6.JWT令牌存在且分析成功,放行

令牌存在且分析成功,执行doFilter方法放行即可。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表