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或…...

数据结构【二叉树】
前言 我们在前面学习了使用数组来实现二叉树,但是数组实现二叉树仅适用于完全二叉树(非完全二叉树会有空间浪费),所以我们本章讲解的是链式二叉树,但由于学习二叉树的操作需要有一颗树,才能学习相关的基本…...
Vue P17-54
18、计算属性 示例:实现姓名的联动效果 可以用插值语法、method {{func()}} 这里必须有 ()表示返回值 在事件处理中,click“func1” 有没有无所谓 computed的计算属性和data中的属性都在vm中,但vm._data里只有后者…...
【自动驾驶】从零开始做自动驾驶小车
文章目录 自动驾驶小车系统、运动底盘的运动学分析和串口通信控制电机PID控制IMU初始化与陀螺仪零点漂移ubuntu基础教程ROS基础键盘控制巡线(雷达避障)雷达跟随视觉跟踪2D建图、2D导航3D建图、3D导航纯视觉建图导航语音控制KCF跟随自主建图建图与导航多机编队WEB浏览器显示摄像…...
一文让你彻底搞懂什么是VR、AR、AV、MR
随着科技的飞速发展,现实世界与虚拟世界的界限变得越来越模糊。各种与现实增强相关的技术如雨后春笋般涌现,令人眼花缭乱。本文将为你详细解读四种常见的现实增强技术:虚拟现实(VR)、增强现实(AR࿰…...

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

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

智慧园区解决方案PPT(53页)
## 1.1 智慧园区背景及需求分析 - 智慧园区的发展历程包括园区规划、经济、产业、企业、管理、理念的转变,强调管理模式创新,关注业务综合化、管理智慧化等发展。 ## 1.2 国家对智慧园区发展的政策 - 涉及多个国家部门,如工信部、住建部、…...
Windows安装MySQL(8.0.37)
安装:https://blog.csdn.net/XLBYYDS/article/details/139711682 注意点: (1)必须安装到C盘系统盘,否则执行 net start mysql 启动服务时,可能会启动失败。 (2)如果安装时出现 The…...

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

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

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

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

【论文阅读】Multi-Camera Unified Pre-Training via 3D Scene Reconstruction
论文链接 代码链接 多摄像头三维感知已成为自动驾驶领域的一个重要研究领域,为基于激光雷达的解决方案提供了一种可行且具有成本效益的替代方案。具有成本效益的解决方案。现有的多摄像头算法主要依赖于单目 2D 预训练。然而,单目 2D 预训练忽略了多摄像…...
深入了解NumPy的原理与使用
文章目录 一、引言二、NumPy的原理1. 多维数组对象2. 广播(Broadcasting)3. 内存效率和速度 三、NumPy的使用1. 创建数组2. 数组操作3. 广播(Broadcasting)示例 四、总结 一、引言 在Python的数据科学和科学计算领域,…...

Linux Centos 环境下搭建RocketMq集群(双主双从)
1、下载rocketmq的包 下载 | RocketMQ 2、配置环境变量 1、编辑环境变量文件:vim /etc/profile2、加入如下配置: #rocketmq 4.9.8 ROCKETMQ_HOME/home/rocketmq/rocketmq-4.9.8 export PATH${ROCKETMQ_HOME}/bin:${PATH}3、刷新配置:source…...

全网最全postman接口测试教程和项目实战~从入门到精通
Postman实现接口测试内容大纲一览: 一、什么是接口?为什么需要接口? 接口指的是实体或者软件提供给外界的一种服务。 因为接口能使我们的实体或者软件的内部数据能够被外部进行修改。从而使得内部和外部实现数据交互。所以需要接口。 比如&…...

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

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

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...