基于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库的…

浏览器缓存

浏览器缓存是指用户在访问web页面时,将一些静态资源(js,css,图片)缓存到本地硬盘(大:1T)或内存(8G,16G)中,当下次访问页面时,不用向服务端发送请求请求资源,直接从本地加载资源,可以提高用户体验 分类:强缓存和协商缓存 一、强缓存:是指用户第一次请求资源成功后,会将响应头字…

研究领域知名课题组调研

Visual SLAM&#xff1a; reference: [connect paper]{https://www.connectedpapers.com/}https://zhuanlan.zhihu.com/p/130530891 德国慕尼黑工业大学计算机视觉组 研究方向&#xff1a;三维重建、机器人视觉、深度学习、视觉 SLAM 等 实验室主页&#xff1a;https://vision…

MySQL如何存储表情符号?

存储表情符号 默认mysql的字符集是utf8&#xff0c;排序规则为 utf8_general_ci INSERT INTO department (name) VALUES (&#x1f604;) 在存储表情的时候会报 1366 - Incorrect string value: \xF0\x9F\x98\x84 for column name at row 1, Time: 0.007000s 这时需要修改字符集…

Socket.D v2.3 发布(打通前端与后端)

基于事件和语义消息流的网络应用层协议。 有用户说&#xff0c;“Socket.D 之于 Socket&#xff0c;尤如 Vue 之于 Js、Mvc 之于 Http”。支持 tcp, udp, ws, kcp 传输。 主要特性 基于事件&#xff0c;每个消息都可事件路由所谓语义&#xff0c;通过元信息进行语义描述流关…

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…

TCP服务器和客户端的创建步骤

TCP服务器的实现流程&#xff1a;一、创建套接字&#xff08;socket函数&#xff09;&#xff1a;通信域选择IPV4网络协议、套接字类型选择流式&#xff1b; int sockfd socket(AF_INET,SOCK_STREAM,0); //通信域选择IPV4、套接字类型选择流式二、填充服务器的网络信息结构体&…

青动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 操作使用…

程序猿的产品思考:2C与2B产品思维的区别

原创/朱季谦 我最早接触到互联网产品的时候&#xff0c;听到最多的&#xff0c;是做产品要有用户思维&#xff0c;即站在用户角度去看待产品。这个先入为主的概念&#xff0c;在很长一段时间里&#xff0c;都被我效作经典。然而也在很长一段时间里&#xff0c;我竟混淆了其中的…

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 …

您的计算机已被[datastore@cyberfear.com].mkp勒索病毒感染?恢复您的数据的方法在这里!

导言&#xff1a; 在数字化时代&#xff0c;网络安全问题愈发严峻&#xff0c;而[datastorecyberfear.com].mkp [hendersoncock.li].mkp [myersairmail.cc].mkp勒索病毒正是其中一个颇具威胁的恶意软件。本章将深入剖析[datastorecyberfear.com].mkp [hendersoncock.li].mkp […

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…