基于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.rhkb.cn/news/238073.html

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

相关文章

C语言入门教程,C语言学习教程(第三部分:C语言变量和数据类型)一

第三部分&#xff1a;C语言变量和数据类型 本章也是C语言的基础知识&#xff0c;主要讲解变量、数据类型以及运算符&#xff0c;这其中涉及到了数据的存储格式以及不同进制。 一、大话C语言变量和数据类型 在《数据在内存中的存储&#xff08;二进制形式存储&#xff09;》一…

性能分析与调优: Linux 内存观测工具

目录 一、实验 1.环境 2.vmstat 3.PSI 4.swapon 5.sar 6.slabtop 7.numstat 8.ps 9.top 10.pmap 11.perf 12.bpftrace 二、问题 1.接口读写报错 2.slabtop如何安装 3.numactl如何安装 4.numad启动服务与关闭NUMA 5. perf如何安装 6. kernel-lt-doc与kern…

MySQL:索引失效场景总结

1 执行计划查索引 通过执行计划命令可以查看查询语句使用了什么索引。 EXPLAIN SELECT * FROM ods_finebi_area WHERE areaName = 福建 执行查询计划后,key列的值就是被使用的索引的名称,若key列没有值表示查询未使用索引。 2 在什么列上创建索引 (1)列经常被用于where…

Multi-View-Information-Bottleneck

encoder p θ ( z 1 ∣ v 1 ) _θ(z_1|v_1) θ​(z1​∣v1​)&#xff0c;D S K L _{SKL} SKL​ represents the symmetrized KL divergence. I ˆ ξ ( z 1 ; z 2 ) \^I_ξ(z_1; z_2) Iˆξ​(z1​;z2​) refers to the sample-based parametric mutual information estimatio…

【PyTorch简介】3.Loading and normalizing datasets 加载和规范化数据集

Loading and normalizing datasets 加载和规范化数据集 文章目录 Loading and normalizing datasets 加载和规范化数据集Datasets & DataLoaders 数据集和数据加载器Loading a Dataset 加载数据集Iterating and Visualizing the Dataset 迭代和可视化数据集Creating a Cust…

memory泄露分析方法(java篇)

#memory泄露主要分为java和native 2种&#xff0c;本文主要介绍java# 测试每天从monkey中筛选出内存超标的app&#xff0c;提单流转到我 首先&#xff0c;辨别内存泄露类型&#xff08;java&#xff0c;还是native&#xff09; 从采到的dumpsys_meminfo_pid看java heap&…

网络技术基础入门全套实验-厦门微思网络CCNA实验手册

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 微思简介&#xff08;https://www.xmws.cn) 微思成立于2002年&#xff0c;是一个诚信敬业、积极向上、充满活力、专注技术服务的企业。 微思获得了八…

LeetCode讲解篇之2280. 表示一个折线图的最少线段数

文章目录 题目描述题解思路题解代码 题目描述 题解思路 折线图中如果连续的线段共线&#xff0c;那么我们可以可以将其合并成一条线段 首先将坐标点按照横坐标升序排序 然后遍历数组 我们可以通过计算前一个线段的斜率和当前线段的斜率来判断是否共线 如果二者相等&#x…

Open3D 两片点云的最小/最大距离(23)

Open3D 两片点云的最小/最大距离(23) 一、效果展示二、使用步骤1.代码三、cloudcompare量距小工具一、效果展示 算法与实际量测的结果保持一致,输出最近距离和对应点 二、使用步骤 1.代码 import open3d as o3d import numpy as np# 读取点云数据 cloud_2 = o3d.io.re…

硬盘无法写入文件的解决方法 在Mac中的特殊符号如何打 tuxera ntfs for Mac 磁盘读写工具

今天将为大家介绍一下怎么在Mac中输入特殊符号&#xff0c;希望能够给大家带来帮助。 图&#xff1a;Mac中的特殊符号 苹果符号 按下ShiftOptionK就可以插入Apple logo了&#xff0c;不过要注意的是&#xff0c;在Windows可能直接显示为一个框框&#xff0c;而Linux系统则有可…

uni微信小程序强制用户更新版本

强制更新的代码参考官方文档 uni.getUpdateManager() | uni-app官网 我这边的如下&#xff1a; //检查版本更新const updateManager uni.getUpdateManager();updateManager.onCheckForUpdate(function (res) {// 请求完新版本信息的回调console.log(res.hasUpdate, "是…

基于java的SSM框架实现在线投稿网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现在线投稿网站系统演示 摘要 随着计算机技术的飞速发展&#xff0c;稿件也已进入信息化时代。为了使稿件管理更高效、更科学&#xff0c;决定开发投稿审稿系统。 本文采用自顶向下的结构化的系统分析方法&#xff0c;阐述了一个功能全面的投稿审稿系统…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -全局异常统一处理实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

GPT实战系列-简单聊聊LangChain搭建本地知识库准备

GPT实战系列-简单聊聊LangChain搭建本地知识库准备 LangChain 是一个开发由语言模型驱动的应用程序的框架&#xff0c;除了和应用程序通过 API 调用&#xff0c; 还会&#xff1a; 数据感知 : 将语言模型连接到其他数据源 具有代理性质 : 允许语言模型与其环境交互 LLM大模型…

Linux-命名管道

文章目录 前言一、命名管道接口函数介绍二、使用步骤 前言 上章内容&#xff0c;我们介绍与使用了管道。上章内容所讲的&#xff0c;是通过pipe接口函数让操作系统给我们申请匿名管道进行进程间通信。 并且这种进程间通信一般只适用于父子进程之间&#xff0c;那么对于两个没有…

创建一个郭德纲相声GPTs

前言 在这篇文章中&#xff0c;我将分享如何利用ChatGPT 4.0辅助论文写作的技巧&#xff0c;并根据网上的资料和最新的研究补充更多好用的咒语技巧。 GPT4的官方售价是每月20美元&#xff0c;很多人并不是天天用GPT&#xff0c;只是偶尔用一下。 如果调用官方的GPT4接口&…

打造VR数字乡村文旅新品牌,VR全景技术助力乡村振兴

新年伊始&#xff0c;各地乡村特色产业都在蓬勃发展&#xff0c;让冬日里的乡村重新焕发了新的活力。并且在这个冬季&#xff0c;各地还依托生态资源优势&#xff0c;打造智慧乡村文旅新品牌&#xff0c;激活乡村消费活力&#xff0c;例如有些乡村利用空心村&#xff0c;打造多…

看完这篇带你了解大学生必考安全证书NISP详解

NISP证书详解 NISP证书介绍&#xff1a;NISP证书等级&#xff1a;NISP&#xff08;一级&#xff09;报名&#xff1a;NISP&#xff08;一级&#xff09;课程大纲&#xff1a;NISP&#xff08;二级&#xff09;报名NISP&#xff08;二级&#xff09;课程大纲NISP二级置换CISP指南…

NLP论文阅读记录 - 2021 | WOS 使用深度强化学习及其他技术进行自动文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1. Seq2seq 模型2.2.强化学习和序列生成2.3.自动文本摘要 三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Auto…

IPv6组播--SSM Mapping

概念 SSM(Source-Specific Multicast)称为指定源组播,要求路由器能了解成员主机加入组播组时所指定的组播源。 如果成员主机上运行MLDv2,可以在MLDv2报告报文中直接指定组播源地址。但是某些情况下,成员主机只能运行MLDv1,为了使其也能够使用SSM服务,组播路由器上需要提…