基于Token认证的登录功能实现

  • Session 认证和 Token 认证
  • 过滤器和拦截器

上篇文章我们讲到了过滤器和拦截器理论知识以及 SpringBoot 集成过滤器和拦截器,本篇文章我们使用过滤器和拦截器去实现基于 Token 认证的登录功能。

一、登录校验 Filter 实现

1.1、Filter 校验流程图

  • 获得请求 url
  • 判断请求 url 中是否包含 login ,如果包含,说明是登录操作,放行。
  • 获取请求头中的令牌(Token
  • 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
  • 解析 token ,如果解析失败,返回错误结果(未登录)。
  • 放行
1.2、Filter 校验实现

新建一个 SpringBoot 项目 loginFilter,引入之前文章提到的 JWT 工具类。

JWTUtils代码如下:

package com.duan.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.Map;/*** @author db* @version 1.0* @description JWTUtils* @since 2023/12/31*/
public class JWTUtils {// 密钥private static String signKey = "cxykk1217";// 过期时间private static Long expire = 1000L*60*30; // 30分钟/*** 生成JWT* @param claims JWT第二部分负载payload中存储的内容* @return*/public static String generateJwt(Map<String,Object> claims){String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, signKey).addClaims(claims).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwt).getBody();return claims;}
}

新建 LoginFilter 类并实现 Filter ,在 doFilter 方法中进行登录校验。代码如下:

package com.duan.filter;import com.alibaba.fastjson.JSONObject;
import com.duan.pojo.Result;
import com.duan.utils.JWTUtils;
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;/*** @author db* @version 1.0* @description LoginFilter* @since 2024/1/11*/
@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;// 1. 获得请求路径String url = httpServletRequest.getRequestURL().toString();// 2. 判断请求的资源路径if(url.contains("/login")){// 登录功能,放行chain.doFilter(request,response);return;}// 3. 获取请求头tokenString token = httpServletRequest.getHeader("token");if(token == null){// 返回登录页面Result noLogin = Result.error("NO_LOGIN");// 使用原始方式给客户端响应数据// 把noLogin 对象转成json字符串返回String jsonString = JSONObject.toJSONString(noLogin);httpServletResponse.getWriter().write(jsonString);return;}// 4. 解析tokentry{JWTUtils.parseJWT(token);}catch (Exception e){// token存在问题// 返回登录页面Result noLogin = Result.error("NO_LOGIN");// 使用原始方式给客户端响应数据// 把noLogin 对象转成json字符串返回String jsonString = JSONObject.toJSONString(noLogin);httpServletResponse.getWriter().write(jsonString);return;}// 5. token解析成功,放行chain.doFilter(request,response);}
}

注意:使用 @WebFilter 配置过滤器时,启动类上一定要使用 @ServletComponentScan 注解。

启动程序,通过 postman 来访问 login 和 getUser 方法。


代码地址:https://gitee.com/duan138/practice-code/tree/dev/loginFilter

二、登录校验拦截器实现

2.1、Interceptor 校验流程图

  • 获得请求 url
  • 判断请求 url 中是否包含 login ,如果包含,说明是登录操作,放行。
  • 获取请求头中的令牌(Token
  • 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
  • 解析 token ,如果解析失败,返回错误结果(未登录)。
  • 放行

通过流程图可以看出,过滤器和拦截器实现的流程是一样的,只不过实现方式不一样。

2.2、Interceptor 校验

新建一个 SpringBoot 项目 loginInterceptor,引入之前文章提到的 JWT 工具类。

JWTUtils 代码如下:

package com.duan.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.Map;/*** @author db* @version 1.0* @description JWTUtils* @since 2023/12/31*/
public class JWTUtils {// 密钥private static String signKey = "cxykk1217";// 过期时间private static Long expire = 1000L*60*30; // 30分钟/*** 生成JWT* @param claims JWT第二部分负载payload中存储的内容* @return*/public static String generateJwt(Map<String,Object> claims){String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, signKey).addClaims(claims).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwt).getBody();return claims;}
}

新建 LoginInterceptor 类并实现 HandlerInterceptor,在 preHandle 方法中进行登录校验。代码如下:


package com.duan.handler;import com.alibaba.fastjson.JSONObject;
import com.duan.pojo.Result;
import com.duan.utils.JWTUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author db* @version 1.0* @description LoginInterceptor* @since 2023/12/20*/
@Component
public class LoginInterceptor implements HandlerInterceptor {// 目标方法执行前调用  true:放行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {// 1. 获得请求路径String url = request.getRequestURL().toString();// 2. 判断请求的资源路径if(url.contains("/login")){// 登录功能,放行return true;}// 3. 获取请求头tokenString token = request.getHeader("token");if(token == null){// 返回登录页面Result noLogin = Result.error("NO_LOGIN");// 使用原始方式给客户端响应数据// 把noLogin 对象转成json字符串返回String jsonString = JSONObject.toJSONString(noLogin);response.getWriter().write(jsonString);return false;}// 4. 解析tokentry{JWTUtils.parseJWT(token);}catch (Exception e){// token存在问题// 返回登录页面Result noLogin = Result.error("NO_LOGIN");// 使用原始方式给客户端响应数据// 把noLogin 对象转成json字符串返回String jsonString = JSONObject.toJSONString(noLogin);response.getWriter().write(jsonString);return false;}// 5. token解析成功,放行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("Completion...");}
}

在 config 包中 LoginInterceptorConfig 方法配置新建的 loginInterceptor。


package com.duan.config;import com.duan.handler.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author db* @version 1.0* @description LoginInterceptorConfig  注册拦截器* @since 2023/12/20*/
@Configuration
public class LoginInterceptorConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(loginInterceptor).addPathPatterns("/**");}
}

启动程序,通过 postman 来访问 login 和 getUser 方法。

代码地址:https://gitee.com/duan138/practice-code/tree/dev/loginInterceptor

三、总结

通过过滤器和拦截器实现基于 Token 的登录功能,加深了对过滤器和拦截器的理解,同时也梳理了基于 Token 认证登录的流程,在现在项目中常用的是基于 SpringSecurity + JWT 登录认证方式,后续我们来看一看基于 Spring security + JWT 怎么去实现登录控制。


参考

1.https://space.bilibili.com/1809189461


改变你能改变的,接受你不能改变的,关注公众号:程序员康康,一起成长,共同进步。

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

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

相关文章

Gradle的安装及源替换步骤详解

工具介绍 Gradle是一款强大的构建工具&#xff0c;用于管理项目的依赖关系和构建过程。在使用Gradle之前&#xff0c;我们需要先进行安装&#xff0c;并可能需要更改默认的依赖源&#xff0c;以提高下载速度。下面是一步步的Gradle安装及源替换指南。 第一步&#xff1a…

Repo命令与git的关系

Repo命令与git的关系是很密切的。 我们都知道&#xff0c;git是一个开源的版本控制系统&#xff0c;常用在大型项目的管理上。 我们对repo的使用和了解就比较少了。Repo是一个基于Git构建出来的工具&#xff0c;它的出现不是为了取代Git&#xff0c;而是为了更方便开发者使用Gi…

使用PE信息查看工具和Beyond Compare文件比较工具排查dll库文件版本不对的问题

目录 1、问题说明 2、修改了代码&#xff0c;但安装版本还是有问题 3、使用PE信息查看工具查看音视频库文件&#xff08;二进制&#xff09;的时间戳 4、使用Beyond Compare比较两个库文件的差异 5、找到原因 6、最后 C软件异常排查从入门到精通系列教程&#xff08;专栏…

Python 文本处理库之chardet使用详解

概要 当处理文本数据时&#xff0c;经常会遇到各种不同的字符编码。这可能导致乱码和其他问题&#xff0c;因此需要一种方法来准确识别文本的编码。Python中的chardet库就是为了解决这个问题而设计的&#xff0c;它可以自动检测文本数据的字符编码。本文将深入探讨chardet库的…

git 的安装

git 的安装 在我们开始使用 Git 前&#xff0c;需要将它安装在我们的电脑上。即便已经安装&#xff0c;最好将它升级到最新的版本。 我们可以通过软件包或者其它安装程序来安装&#xff0c;或者下载源码编译安装。 本文只介绍通过在 windows 上安装软件包的方式&#xff0c;其…

大模型实战05——LMDeploy大模型量化部署实践

大模型实战05——LMDeploy大模型量化部署实践 1、大模型部署背景 2、LMDeploy简介 3、动手实践环节——安装、部署、量化 注 笔记内容均为截图 笔记课程视频地址&#xff1a;https://www.bilibili.com/video/BV1iW4y1A77P/?spm_id_from333.788&vd_source2882acf8c823ce…

NLP论文阅读记录 - 2022 | WOS 一种新颖的优化的与语言无关的文本摘要技术

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.前提三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 A Novel Optimized Language-Independent Text Summarization Techni…

青动CRM-E售后 售后工单CRM系统 erp系统 带前端小程序全开源可二开

应用介绍 一款基于FastAdminThinkPHP和uniapp开发的CRM售后管理系统&#xff0c;旨在助力企业销售售后全流程精细化、数字化管理&#xff0c;主要功能&#xff1a;客户、合同、工单、任务、报价、产品、库存、出纳、收费&#xff0c;适用于&#xff1a;服装鞋帽、化妆品、机械机…

操作系统复习 七、八章

操作系统复习 七、八章 文章目录 操作系统复习 七、八章第七章 内存管理内存管理的基本要求和原理覆盖与交换连续分配管理方式非连续分配管理方式基本分段存储管理方式段页式管理方式补充 第八章 虚拟内存虚拟内存的基本概念请求分页管理方式易混知识点页面置换算法页面分配策略…

Apollo之原理和使用讲解

文章目录 1 Apollo1.1 简介1.1.1 背景1.1.2 简介1.1.3 特点 1.2 基础模型1.3 Apollo 四个维度1.3.1 application1.3.2 environment1.3.3 cluster1.3.4 namespace 1.4 本地缓存1.5 客户端设计1.5.1 客服端拉取原理1.5.2 配置更新推送实现 1.6 总体设计1.7 可用性考虑 2 操作使用…

Flink-SQL——动态表 (Dynamic Table)

动态表 (Dynamic Table) 文章目录 动态表 (Dynamic Table)DataStream 上的关系查询动态表 & 连续查询(Continuous Query)在流上定义表连续查询更新和追加查询查询限制 表到流的转换总结 SQL 和关系代数在设计时并未考虑流数据。因此&#xff0c;在关系代数(和 SQL)之间几乎…

ubuntu18.04 TensorRT 部署 yolov5-7.0推理

文章目录 1、环境配置2、推理部分2.1、检测2.2、分类2.3、分割2.4、INT8 量化 1、环境配置 链接: TensorRT cuda环境安装 2、推理部分 下载yolov5对应版本的包 https://github.com/wang-xinyu/tensorrtx/tree/master/yolov5 2.1、检测 1、源码模型下载 git clone -b v7.0 …

C# 导出EXCEL 和 导入

使用winfrom简单做个界面 选择导出路径 XLSX起名字 打开导出是XLSX文件 // 创建Excel应用程序对象Excel.Application excelApp new Excel.Application();excelApp.Visible false;// 创建工作簿Excel.Workbook workbook excelApp.Workbooks.Add(Type.Missing);Excel.Works…

F-score 和 Dice Loss 原理及代码

文章目录 1. F-score1. 1 原理1. 2 代码2. Dice Loss2.1 原理2.2 代码 通过看开源图像语义分割库的源码&#xff0c;发现它对 Dice Loss 的实现方式&#xff0c;是直接调用 F-score 函数&#xff0c;换言之&#xff0c;Dice Loss 是 F-score的特殊情况。于是就研究了一下这背后…

训练FastestDet(Anchor-Free、参数量仅0.24M),稍改代码使得符合YOLO数据集排布

文章目录 0 参考链接1 准备数据1.1 使用以下代码生成绝对路径的txt文件1.2 在config文件夹下新建一个xxx.names文件 2 配置训练参数3 稍改代码使得符合YOLO数据集排布4 开始训练 0 参考链接 官方的代码&#xff1a;FastestDet 1 准备数据 我已有的数据集排布&#xff1a;&am…

【Fiddler抓包】微信扫码访问链接打不开网页

又来每天进步一点点~~~ 背景&#xff1a;某天发版的时候&#xff0c;手机连接电脑抓包查看用户登录之前的sessionID&#xff0c;由于业务需要&#xff0c;是需要用户登录微信扫码跳转至某一页面的&#xff0c;微信&#xff08;分身&#xff09;扫码成功&#xff0c;跳转时打不…

【已解决】fatal: Authentication failed for ‘https://github.com/.../‘

文章目录 异常原因解决方法 异常原因 在 Linux 服务器上使用git push命令&#xff0c;输入用户名和密码之后&#xff0c;总会显示一个报错&#xff1a; fatal: Authentication failed for https://github.com/TianJiaQi-Code/Linux.git/ # 致命&#xff1a;无法通过验证访问起…

5V高细分步进电机驱动芯片选型分析

单通道5V高细分步进电机GC6139 GC6106 GC6107 GC6119 GC6151 GC6236 GC8558 它们应用在摇头机&#xff0c;X,Y控制&#xff0c;聚焦控制等产品上。其中GC8558为24V H 桥驱动&#xff0c;大电流&#xff0c;具有短地短电源保护&#xff0c;限流保护等功能。

从 PDF 删除PDF 页面的 10 大工具

PDF 文件是全世界几乎每个人最常用的页面之一。借助 PDF 文件&#xff0c;您可以通过任何在线或离线媒体轻松共享信息。但是&#xff0c;如果您想编辑这些 PDF 文件&#xff0c;那么这个过程就很难改变&#xff0c;因为保持文件的原始形式和质量很重要。应该注意的是&#xff0…

java数据结构与算法:双链表 LinkedList

双链表 LinkedList 实现代码 package com.lhs;public class LinkedList<E> implements List<E>{// 定义链表长度private int size;// 定义头节点private Node<E> first;// 定义尾节点private Node<E> last;// 内部类&#xff0c;定义节点public stat…