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

news/2025/2/28 23:44:57/

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

我们要实现登录校验过滤器,就要首先明白登录校验过滤器的实现思路。登录校验过滤器是用来实现登录校验的。那么首先思考第一个问题,所有的请求都需要校验吗?

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

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

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

二.代码实现

package com.gjw.filter;import com.alibaba.fastjson.JSONObject;
import com.gjw.pojo.Result;
import com.gjw.util.JwtUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import java.io.IOException;@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 1.获取请求的urlString requestURL = request.getRequestURL().toString();log.info("获取请求的URL:{}",requestURL);// 2.判断url中是否包含"login"if (requestURL.contains("login")) {log.info("登录操作,直接放行......");// 如果包含,直接放行filterChain.doFilter(servletRequest,servletResponse);return;}// 3.不包含则获取JWT令牌并检验String jwt = request.getHeader("token");// 4.检验JWT令牌是否存在,如果不存在,则返回错误结果(未登录)if(!StringUtils.hasLength(jwt)) {   // jwt不存在或者为null,返回falselog.info("请求头token为空,返回登录页面......");Result error = Result.error("NOT_LOGIN");String notLogin = JSONObject.toJSONString(error);// 没有RestController注解,无法将直接return的数据以JSON格式返回,需要强转为JSON  手动转换:对象----->JSON格式的数据response.getWriter().write(notLogin);  // 通过response对象返回JSON格式的数据return;}// 5.如果存在,校验JWT令牌是否正确,如果解析失败,则返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);     // 解析成功放行} catch (Exception e) {     // 失败捕获异常e.printStackTrace();log.info("解析失败,返回未登录的错误信息......");Result error = Result.error("NOT_LOGIN");String notLogin = JSONObject.toJSONString(error);// 没有RestController注解,无法将直接return的数据以JSON格式返回,需要强转为JSON  手动转换:对象----->JSON格式的数据response.getWriter().write(notLogin);  // 通过response对象返回JSON格式的数据return;}// 6.JWT令牌存在且解析成功,放行log.info("令牌合法,放行。");filterChain.doFilter(servletRequest,servletResponse);}
}

 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的工具包,首先引入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.52</version>
</dependency>

然后使用JSONObject将对象转为JSON格式的字符串,然后我们将该字符串相应给浏览器。通过响应对象response调用其中的getWriter()获取一个输出流,再调用里面的writer()方法将要响应未登陆的数据notLogin传递给前端。然后直接结束方法,跳转到登录页面。

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

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

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

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


http://www.ppmy.cn/news/1575624.html

相关文章

CSP-S 2022 T1假期计划

CSP-S 2022 T1假期计划 先思考暴力做法&#xff0c;题目需要找到四个不相同的景点&#xff0c;那我们就枚举这四个景点&#xff0c;判断它们之间的距离是否符合条件&#xff0c;条件是任意两个点之间的距离是否大于 k k k&#xff0c;所以我们需要求出任意两点之间的距离。常用…

【Java项目】基于Spring Boot的旅游管理系统

【Java项目】基于Spring Boot的旅游管理系统 技术简介&#xff1a;采用Java技术、Spring Boot框架、MySQL数据库等实现。 系统简介&#xff1a;旅游管理系统是一个基于Web的在线平台&#xff0c;主要分为前台和后台两大功能模块。前台功能模块包括&#xff08;1&#xff09;首…

Redis-列表结构实操

列表实操 前言简单练习基本的LPUSH和RPUSH操作列表元素的访问与修改列表元素的插入和删除列表阻塞操作 困难练习分页列表游标机制业务上考虑直接访问任意页如何高效分页局限性小结 实现限时排行版轮换消息队列可靠性实现分布式锁实现 总结 前言 之前总结过-列表的数据结构,但是…

go 查看版本

个人学习笔记 1. 打开终端&#xff08;或命令提示符&#xff09; 在 Windows 上&#xff0c;使用 cmd 或 PowerShell。在 macOS 或 Linux 上&#xff0c;使用终端应用程序。 2. 运行以下命令 go version 3. 查看输出 命令执行后&#xff0c;终端会显示已安装的 Go 版本&…

JAVA【微服务】Spring AI 使用详解

目录 一、前言二、Spring AI 概述2.1 什么是 Spring AI2.2 Spring AI 特点2.3 Spring AI 带来的便利2.4 Spring AI 应用领域2.4.1 聊天模型2.4.2 文本到图像模型2.4.3 音频转文本2.4.4 嵌入大模型使用2.4.5 矢量数据库支持2.4.6 数据工程 ETL 框架三、Spring AI 对接 ChatGPT3.…

设计模式-(装饰器,适配器,观察者,外观)

装饰器模式 概念&#xff1a; 它允许在不改变对象自身的情况下&#xff0c;动态地给对象添加额外的功能。通过使用装饰器模式&#xff0c;可以在运行时对对象进行扩展&#xff0c;而不需要创建大量的子类 应用&#xff1a; 当你希望在不修改原有类的情况下&#xff0c;给对…

软件测试丨计算机视觉场景下的边缘计算与测试场景

在计算机视觉场景中&#xff0c;边缘计算与测试场景的结合具有重要意义。以下是两者的关键点&#xff1a; 1. 边缘计算在计算机视觉中的作用 边缘计算将计算任务从云端转移到靠近数据源的边缘设备&#xff0c;如摄像头、传感器等&#xff0c;具有以下优势&#xff1a; 低延迟…

北京大学DeepSeek与AIGC应用(PDF无套路下载)

近年来&#xff0c;人工智能技术飞速发展&#xff0c;尤其是大模型和生成式AI&#xff08;AIGC&#xff09;的突破&#xff0c;正在重塑各行各业的生产方式与创新路径。 北京大学联合DeepSeek团队推出的内部研讨教程《DeepSeek与AIGC应用》&#xff0c;以通俗易懂的方式系统解…