当前位置: 首页 > news >正文

JavaWeb阶段学习知识点(二)

登录校验和JWT令牌实现

JWT使用方式

创建一个springboot项目,pom.xml引入jwt依赖

        <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- 针对jdk17或者报错内容为:java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter 的小伙伴加一下下面的依赖 --><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

在测试类中,定义一个测试方法,测试jwt令牌生成

package com.jwz;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class test {/*** 生成jwt*/@Testvoid testSetJwt() {Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put("name","xiaoji");/*** builder:用来构建jwt令牌* signWith: 生成jwt令牌使用的数字算法(jwt.io),官网有,参数一指定算法,参数二就是签名秘钥,这个随便写,但是切记不要少于5个字符,否则报错* setClaims:设置自定义数据(载荷)* setExpiration:设置令牌有效期,System.currentTimeMillis()+3600 当前时间+3600秒,也就是3600*1000毫秒后令牌过期,就是设置有效期为一小时* compact:调用compact可以拿到一个字符串类型的返回值*/String jinweizhe = Jwts.builder().signWith(SignatureAlgorithm.HS256, "jinweizhe").setClaims(claims).setExpiration(new Date(System.currentTimeMillis() + 3600*1000)).compact();System.out.println("生成的jwt为: "+jinweizhe); // 这个打印的就是jwt令牌// 生成的jwt为: eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb2ppIiwiaWQiOjEsImV4cCI6MTcxNjIxODU2OH0.4-yMVfNWyb87TFryq8FJTiH_AAXLsmYGOFVybyjK15g}/*** 解析jwt*/@Testvoid testGetJwt(){/*** setSigningKey:指定签名秘钥* parseClaimsJws:传入jwt令牌* getBody:拿到自定义内容*/Claims jinweizhe = Jwts.parser().setSigningKey("jinweizhe").parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb2ppIiwiaWQiOjEsImV4cCI6MTcxNjIxODU2OH0.4-yMVfNWyb87TFryq8FJTiH_AAXLsmYGOFVybyjK15g").getBody();System.out.println("解析到的jwt为: "+jinweizhe);  // 解析到的jwt为: {name=xiaoji, id=1, exp=1716218568}}
}
  • JWT校验时使用的签名秘钥,必须和生成IWT令牌时使用的秘钥是配套的
  • 如果JWT令牌解析校验时报错,则说明JWT令牌被篡改 或 失效了,令牌非法。

过滤器filter的使用操作

  • 定义Filter:定义一个类,实现 Filter 接口,并重写其所有方法。
  • 配置Filter:filter类上加 @WebFiter 注解,配置拦截资源的路径。引导类上加 @ServletComponentscan 开启Servlet组件支持,

登录校验流程

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

在SpringBoot项目下,新建一个utils包和DemoFilter类

这里说明一下,下面用到的Result和JwtUtils都是工具包,下面有完整的项目代码,里面是有包含的,这里就不写出来了,可以往下翻找到完整项目代码

DemoFilter类内容如下

package com.jwz.login;import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
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 = "/*")  // 拦截所有的请求
// @WebFilter(urlPatterns = "/emps/*") // 访问emps下的所有资源的,都会被拦截
// @WebFilter(urlPatterns = "/login") // 拦截具体接口
public class DemoFilter implements Filter {// 还有init和destroy分别对应初始化方法和销毁方法,都只会调用一次,这两个不用重写,因为查看Filter源码会发现底层已经默认调用了,当然,想重写也可以// 这里只关注doFilter即可,他会在拦截到请求之后开始调用,会调用多次@Override // 拦截到请求之后调用,会调用多次,拦截到接口需要放行,否则接口不返回数据public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// System.out.println("拦截到请求了...放行之前的逻辑");// // 放行接口// // 参数1:请求对象  参数2:响应对象// // 放行后可以发现能正常返回数据了// filterChain.doFilter(servletRequest,servletResponse);// System.out.println("拦截到请求了...放行之后的逻辑");// 下面是登录校验的实现思路HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse resp = (HttpServletResponse) servletResponse;// 将请求头和响应头都设置utf-8的格式,避免请求和响应结果有中文造成了乱码req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("application/json; charset=UTF-8");//1.获取请求ur1.String url = req.getRequestURL().toString();log.info("请求的url:{}",url);//2.判断请求url中是否包含login,如果包含,说明是获录操作,放行。if(url.contains("login")){log.info("登录操作,直接放行");filterChain.doFilter(servletRequest,servletResponse);return; // 停止代码继续向下执行}//3.获取请求头中的令牌(token)。String token = req.getHeader("token");//4.判断令牌是否存在、如果不存在,返回错误结果(未发录)if(!StringUtils.hasLength(token)){ // 判断字符串是否有长度log.info("请求头token为空,返回未登录信息");Result error = Result.error("未登录"); // 这里的Result是一个工具类,笔记下面的完整项目里面有工具文件代码// 手动转换 对象 -- json -----> 阿里巴巴fastJSON工具包(https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2/2.0.50)// 去上面地址复制代码到pom.xml依赖下载一下String noLogin = JSONObject.toJSONString(error); // 获取到json字符串(对象转成了json字符串)resp.getWriter().write(noLogin); // 将结果响应给浏览器return;}//5.解析token,如果解析失败,返回误结果(未录)// 这里的JwtUtils也是个工具类,跟上面的Result一样,下翻完整代码里面有工具类代码提供try {JwtUtils.parseJWT(token);} catch (Exception e) {// e.printStackTrace();log.info("令牌解析失败,返回未登录的错误信息");Result error = Result.error("未登录");String noLogin = JSONObject.toJSONString(error); // 获取到json字符串(对象转成了json字符串)resp.getWriter().write(noLogin); // 将结果响应给浏览器return;}//6.放行。log.info("令牌合法,直接放行");filterChain.doFilter(servletRequest, servletResponse);}
}

启动类新增一个注解

package com.jwz;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@ServletComponentScan // 开启了对servlet组件的支持
@SpringBootApplication
public class LoginVeifillyApplication {public static void main(String[] args) {SpringApplication.run(LoginVeifillyApplication.class, args);}}

测试用的controller

package com.jwz.login;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@Slf4j
@RestController
public class loginController {@PostMapping("/login")public Result login(@RequestBody loginEntity login){// 登陆成功,生成jwt并下发jwt返回给前端Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put

相关文章:

JavaWeb阶段学习知识点(二)

登录校验和JWT令牌实现 JWT使用方式 创建一个springboot项目,pom.xml引入jwt依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- 针对jdk17或…...

数据结构【二叉树】

前言 我们在前面学习了使用数组来实现二叉树&#xff0c;但是数组实现二叉树仅适用于完全二叉树&#xff08;非完全二叉树会有空间浪费&#xff09;&#xff0c;所以我们本章讲解的是链式二叉树&#xff0c;但由于学习二叉树的操作需要有一颗树&#xff0c;才能学习相关的基本…...

Vue P17-54

18、计算属性 示例&#xff1a;实现姓名的联动效果 可以用插值语法、method {{func()}} 这里必须有 &#xff08;&#xff09;表示返回值 在事件处理中&#xff0c;click“func1” 有没有无所谓 computed的计算属性和data中的属性都在vm中&#xff0c;但vm._data里只有后者…...

【自动驾驶】从零开始做自动驾驶小车

文章目录 自动驾驶小车系统、运动底盘的运动学分析和串口通信控制电机PID控制IMU初始化与陀螺仪零点漂移ubuntu基础教程ROS基础键盘控制巡线(雷达避障)雷达跟随视觉跟踪2D建图、2D导航3D建图、3D导航纯视觉建图导航语音控制KCF跟随自主建图建图与导航多机编队WEB浏览器显示摄像…...

一文让你彻底搞懂什么是VR、AR、AV、MR

随着科技的飞速发展&#xff0c;现实世界与虚拟世界的界限变得越来越模糊。各种与现实增强相关的技术如雨后春笋般涌现&#xff0c;令人眼花缭乱。本文将为你详细解读四种常见的现实增强技术&#xff1a;虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff0…...

Python设计模式 - 简单工厂模式

定义 简单工厂模式是一种创建型设计模式&#xff0c;它通过一个工厂类来创建对象&#xff0c;而不是通过客户端直接实例化对象。 结构 工厂类&#xff08;Factory&#xff09;&#xff1a;负责创建对象的实例。工厂类通常包含一个方法&#xff0c;根据输入参数的不同创建并返…...

L55--- 257.二叉树的所有路径(深搜)---Java版

1.题目描述 2.思路 &#xff08;1&#xff09;因为是求二叉树的所有路径 &#xff08;2&#xff09;然后是带固定格式的 所以我们要把每个节点的整数数值换成字符串数值 &#xff08;3&#xff09;首先先考虑根节点&#xff0c;也就是要满足节点不为空 返回递归的形式dfs(根节…...

智慧园区解决方案PPT(53页)

## 1.1 智慧园区背景及需求分析 - 智慧园区的发展历程包括园区规划、经济、产业、企业、管理、理念的转变&#xff0c;强调管理模式创新&#xff0c;关注业务综合化、管理智慧化等发展。 ## 1.2 国家对智慧园区发展的政策 - 涉及多个国家部门&#xff0c;如工信部、住建部、…...

Windows安装MySQL(8.0.37)

安装&#xff1a;https://blog.csdn.net/XLBYYDS/article/details/139711682 注意点&#xff1a; &#xff08;1&#xff09;必须安装到C盘系统盘&#xff0c;否则执行 net start mysql 启动服务时&#xff0c;可能会启动失败。 &#xff08;2&#xff09;如果安装时出现 The…...

永磁同步电机驱动死区补偿

1 死区效应及补偿 1. 1 死区效应 在本文的电机控制嵌入式系统中,逆变器为三 相电压型桥式逆变电路,如图 1 所示。 在理想状态 下,上桥臂和下桥臂的控制信号满足互补通断原则, 即上桥臂开通时,下桥臂关断,反之亦然。 而在实际 应用中,开关管的通断需要一定的开通时…...

智能体合集

海外版coze: 前端代码助手 后端代码助手&#xff1a; 前端代码助手&#xff1a;...

智能农业管理系统设计

一、引言 随着物联网、云计算和大数据技术的快速发展&#xff0c;智能农业管理系统成为提高农业生产效率、优化资源配置、降低环境污染的重要手段。本设计旨在构建一个集数据采集、传输、处理、分析于一体的智能农业管理系统&#xff0c;为农业生产提供全方位、精准化的服务。 …...

Matlab的Simulink系统仿真(simulink调用m函数)

这几天要用Simulink做一个小东西&#xff0c;所以在网上现学现卖&#xff0c;加油&#xff01; 起初的入门是看这篇文章MATLAB 之 Simulink 操作基础和系统仿真模型的建立_matlab仿真模型搭建-CSDN博客 写的很不错 后面我想在simulink中调用m文件 在 Simulink 中调用 MATLA…...

C语言中操作符详解(一)

众所周知&#xff0c;在我们的C语言中有着各式各样的操作符&#xff0c;并且在此之前呢&#xff0c;我们已经认识并运用了许许多多的操作符&#xff0c;都是诸君的老朋友了昂 操作符作为我们使用C语言的一个非常非常非常重要的工具&#xff0c;诸君一定要加以重视&#xff0c;…...

【论文阅读】Multi-Camera Unified Pre-Training via 3D Scene Reconstruction

论文链接 代码链接 多摄像头三维感知已成为自动驾驶领域的一个重要研究领域&#xff0c;为基于激光雷达的解决方案提供了一种可行且具有成本效益的替代方案。具有成本效益的解决方案。现有的多摄像头算法主要依赖于单目 2D 预训练。然而&#xff0c;单目 2D 预训练忽略了多摄像…...

深入了解NumPy的原理与使用

文章目录 一、引言二、NumPy的原理1. 多维数组对象2. 广播&#xff08;Broadcasting&#xff09;3. 内存效率和速度 三、NumPy的使用1. 创建数组2. 数组操作3. 广播&#xff08;Broadcasting&#xff09;示例 四、总结 一、引言 在Python的数据科学和科学计算领域&#xff0c;…...

Linux Centos 环境下搭建RocketMq集群(双主双从)

1、下载rocketmq的包 下载 | RocketMQ 2、配置环境变量 1、编辑环境变量文件&#xff1a;vim /etc/profile2、加入如下配置&#xff1a; #rocketmq 4.9.8 ROCKETMQ_HOME/home/rocketmq/rocketmq-4.9.8 export PATH${ROCKETMQ_HOME}/bin:${PATH}3、刷新配置&#xff1a;source…...

全网最全postman接口测试教程和项目实战~从入门到精通

Postman实现接口测试内容大纲一览&#xff1a; 一、什么是接口&#xff1f;为什么需要接口&#xff1f; 接口指的是实体或者软件提供给外界的一种服务。 因为接口能使我们的实体或者软件的内部数据能够被外部进行修改。从而使得内部和外部实现数据交互。所以需要接口。 比如&…...

【ARM】MDK Debug模式下Disassembly窗口介绍

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 主要了解Disassembly窗口中包含的内容&#xff0c;和如何利用Disassembly中的内容了解程序的存储和调用情况。 2、 问题场景 对于Disassembly窗口中具体包含的内容不了解&#xff0c;无法合理地应用Disassembly窗口…...

灵活的招聘管理系统有五种方法帮助成功招聘

还记得以前的时代吗&#xff1f;这取决于你的年龄&#xff0c;直到智能手机、流媒体电视和电子邮件出现。今天&#xff0c;任何活着的成年人都经历了技术上的巨大变化&#xff0c;这创造了一种新的行为方式。人才获取也是如此。 一个值得推荐的招聘管理系统 招聘团队被困在满足…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...