spring boot3x登录开发-上(整合jwt)
⛰️个人主页: 蒾酒
🔥系列专栏:《spring boot实战》
🌊山高路远,行路漫漫,终有归途。
目录
前置条件
jwt简介
导依赖
编写jwt工具类
1.配置项直接嵌入代码,通过类名.静态方法使用
2.配置项写到application.yml,交由spring容器管理依赖注入使用
前置条件
已经初始化好一个spring boot项目且版本为3X,项目可正常启动。
作者版本为3.2.2
初始化教程:
新版idea创建spring boot项目-CSDN博客文章浏览阅读2.5k次,点赞60次,收藏66次。本教程对新手小白友好。若根据教程创建出现问题导致失败可下载我提供的源码,在文章最后。本教程较新本文使用的工具以及搭建的springboot版本都是很新版本:idea版本如下spring boot 版本如下:本教程使用的是汉化后的idea。https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501
jwt简介
- JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用间传输和存储信息的一种安全方式。
- 它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
- JWT可以被用作身份验证和授权,通过在服务器和客户端之间传递令牌来验证用户的身份并允许访问受保护的资源。
- 由于JWT是基于数字签名的,所以可以确保数据的完整性和安全性。它的设计简单、易于实现,并且可以跨不同的平台和语言使用。
导依赖
pom.xml:
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
<!-- 如果jdk大于1.8,则还需导入下面依赖--><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>
注意:你的jdk版本如果为1.8导入第一个就行,大于1.8就要导入两个。
编写jwt工具类
JWT(JSON Web Token)工具类在实际开发中通常包含以下一些常用方法:
- 生成JWT:用于生成JWT令牌并返回令牌字符串。
- 解析JWT:用于解析JWT令牌,验证签名,并获取其中的声明信息。
- 验证JWT:用于验证JWT的有效性,包括验证签名、过期时间等。
- 刷新JWT:用户还在操作,马上要快过期时,延长其有效期(无感刷新)。
- 其他辅助方法:例如获取JWT中的特定声明信息,验证JWT是否包含某个声明,等等。
其中生成和解析token是必须的,其他方法根据项目需求设计来决定写不写。
1.配置项直接嵌入代码,通过类名.静态方法使用
jwt工具类如下:
上面五种常用方法已经写好,cv过来直接能用。按需修改也可以。
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;/*** @author mijiupro*/
public class JwtUtils {private static final String SIGN_KEY = "mijiu";// 加密密钥private static final long EXPIRE_TIME = 12 * 60 * 60 * 1000; //到期时间,12小时,单位毫秒private static final byte[] SECRET_KEY = SIGN_KEY.getBytes(StandardCharsets.UTF_8);/*** 生成token令牌* @param claims JWT第二部分负载 payload 中存储的内容* @param subject 主题(用户类型)* @return token*/public static String generateToken(Map<String,Object> claims, String subject) {return Jwts.builder().setId(Claims.ID)//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为令牌的唯一标识。.setSubject("mijiu")//设置主题,一般为用户类型.setIssuedAt(new Date())//设置签发时间.addClaims(claims)//设置负载.signWith(SignatureAlgorithm.HS256, SECRET_KEY)//设置签名算法.setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))//设置令牌过期时间.compact();//生成令牌}/*** 解析token令牌* @param token token令牌* @return 负载*/public static Claims parseToken(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();}/*** 验证token令牌* @param token 令牌* @return 是否有效*/public static boolean validateToken(String token) {try {Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();return true;} catch (Exception e) {return false;}}/*** 刷新Token* @param token 旧的Token令牌* @return 新的Token令牌*/public static String refreshToken(String token) {try {// 解析旧的Token,获取负载信息Claims claims = parseToken(token);// 生成新的Token,设置过期时间和签名算法等参数return generateToken(claims, claims.getSubject());} catch (Exception e) {throw new RuntimeException("无法刷新令牌!", e);}}/*** 从令牌中获取主题信息* @param token 令牌* @return 主题信息(用户类型)*/public static String getSubjectFromToken(String token) {try {Claims claims = parseToken(token); // 解析令牌,获取负载信息return claims.getSubject(); // 返回主题信息} catch (Exception e) {throw new RuntimeException("无法从令牌中获取主题。", e);}}}
编写测试
测试代码如下:
import com.mijiu.commom.util.JwtUtils;
import io.jsonwebtoken.Claims;
import org.junit.jupiter.api.Test;import java.util.Map;public class JwtTest {@Testpublic void testJwt() {// 设置JWT的payloadMap<String, Object> claims = Map.of("username", "mijiu", "role", "admin");// 生成JWTString jwt = JwtUtils.generateToken(claims, "secret");System.out.println("JWT: " + jwt);// 解析JWTClaims claims1 = JwtUtils.parseToken(jwt);// 获取完整的payloadString payload = claims1.toString();System.out.println("Payload: " + payload);}
}
作者目录结构
运行测试代码
测试通过
2.配置项写到application.yml,交由spring容器管理依赖注入使用
jwt工具类如下:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.Map;/*** @author mijiupro*/
@Data
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtUtils {private String secret;//密钥private long expiration;//过期时间/*** 生成token令牌* @param claims JWT第二部分负载 payload 中存储的内容* @param subject 主题(用户类型)* @return token*/public String generateToken(Map<String,Object> claims, String subject) {return Jwts.builder().setId(Claims.ID)//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为令牌的唯一标识。.setSubject("mijiu")//设置主题,一般为用户类型.setIssuedAt(new Date())//设置签发时间.addClaims(claims)//设置负载.signWith(SignatureAlgorithm.HS256, secret)//设置签名算法.setExpiration(new Date(System.currentTimeMillis() + expiration))//设置令牌过期时间.compact();//生成令牌}/*** 解析token令牌* @param token token令牌* @return 负载*/public Claims parseToken(String token) {return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();}/*** 验证token令牌* @param token 令牌* @return 是否有效*/public boolean validateToken(String token) {try {Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();return true;} catch (Exception e) {return false;}}/*** 刷新Token* @param token 旧的Token令牌* @return 新的Token令牌*/public String refreshToken(String token) {try {// 解析旧的Token,获取负载信息Claims claims = parseToken(token);// 生成新的Token,设置过期时间和签名算法等参数return generateToken(claims, claims.getSubject());} catch (Exception e) {throw new RuntimeException("无法刷新令牌!", e);}}/*** 从令牌中获取主题信息* @param token 令牌* @return 主题信息(用户类型)*/public String getSubjectFromToken(String token) {try {Claims claims = parseToken(token); // 解析令牌,获取负载信息return claims.getSubject(); // 返回主题信息} catch (Exception e) {throw new RuntimeException("无法从令牌中获取主题。", e);}}}
注意:此代码用到了lombok的@Data注解,来添加getter 和 setter 方法,请确保有该依赖依赖坐标:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
配置文件添加jwt的配置项
application.yml:
jwt:secret: 123456 #密钥expiration: 43200000 #过期时间 12h
编写测试类
import com.mijiu.commom.util.JwtUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;/*** @author mijiupro*/@RestController
@RequestMapping("/test")
public class TestController {private final JwtUtils jwtUtils;public TestController(JwtUtils jwtUtils) {this.jwtUtils = jwtUtils;}@GetMapping("/get-token")public String getToken() {Map<String, Object> claims = new HashMap<>();claims.put("username", "mijiu");claims.put("role", "admin");return jwtUtils.generateToken(claims,"user");}@GetMapping("/parse-token/{token}")public String parseToken(@PathVariable String token) {return jwtUtils.parseToken(token).toString();}
}
目录结构
启动项目
请求jwt测试接口
生成token接口:
复制token
请求解析token接口并路径传参传入复制的token
测试成功。
相关文章:

spring boot3x登录开发-上(整合jwt)
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途。 目录 前置条件 jwt简介 导依赖 编写jwt工具类 1.配置项直接嵌入代码,通过类名.静态方法使用 2.配置项写到…...
git 克隆拉取代码出现私钥权限问题。
问题反馈: rootdd:~/android/boost-1.74-for-android-r20b# git clone https://github.com/liulilittle/boost-1.74-for-android-r20b.git Cloning into boost-1.74-for-android-r20b... WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0777 for /root/…...

【5G NR】【一文读懂系列】移动通讯中使用的信道编解码技术-卷积码原理
目录 一、引言 二、卷积编码的发展历史 2.1 卷积码的起源 2.2 主要发展阶段 2.3 重要里程碑 三、卷积编码的基本概念 3.1 基本定义 3.2 编码器框图 3.3 编码多项式 3.4 网格图(Trellis)描述 四、MATLAB示例 一、引言 卷积编码,作为数字通信领域中的一项…...

揭开Markdown的秘籍:标题|文字样式|列表
🌈个人主页:聆风吟 🔥系列专栏:Markdown指南、网络奇遇记 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. ⛳️Markdown 标题二. ⛳️Markdown 文字样式2.1 🔔斜体2.2 &…...

移动最小二乘法
移动最小二乘法(Moving Least Square,MLS)主要应用于曲线与曲面拟合,该方法基于紧支撑加权函数(即函数值只在有限大小的封闭域中定义大于零,而在域外则定义为零)和多项式基函数,通过…...

【LeetCode】37. 解数独(困难)——代码随想录算法训练营Day30
题目链接:37. 解数独 题目描述 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&…...
VUE学习——属性绑定
属性绑定,就是给html添加id、class这样类似的操作。 <template><div v-bind:id"dynamicId"><div v-bind:class"dynamicClass">Test</div></div> </template><script>export default{data(){return{…...

vue3 之 通用组件统一注册全局
components/index.js // 把components中的所组件都进行全局化注册 // 通过插件的方式 import ImageView from ./ImageView/index.vue import Sku from ./XtxSku/index.vue export const componentPlugin {install (app) {// app.component(组件名字,组件配置对象)…...

[Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
LeetCode 热题 100---04~07 第一题:移动零 思路 找到每一个为0的元素 然后移到数组的最后 但是需要注意的是 要在给定的数组原地进行修改 并且其他非零元素的相对顺序不能改变 我们采用双指针法 定义两个指针i和j i和j一开始分别都在0索引位置 然后判断j所…...
【问题解决】如何将一个服务器的docker迁移到另一个服务器
要将Docker容器从一台机器迁移到另一台机器,可以按照以下步骤操作: 在机器A上提交容器为镜像: 使用docker commit命令将运行中的容器保存为新的镜像。这里需要容器的ID或名称,以及你想要命名的目标镜像名。 docker commit [容器…...
C++单例模式详解
目录 0. 前言 1. 懒汉式单例模式 1.1 最简单的单例模式 1.2 防止内存泄漏 1.2.1 智能指针的方法 1.2.2 静态嵌套的方法 1.3 保证线程安全 1.4 C11版本的优雅解决方案 2. 饿汉式单例模式 0. 前言 起因是在程序中重复声明了一个单例模式的变量,后来程序怎么调…...

LLM应用开发与落地:流式响应
一、背景 最近智能客服产品给到一个游戏客户那边,客户那边的客服负责人体验后认为我们产品回答的准确率是还是比较高的。同时,他反馈了几个需要改进的地方,其中一个就是机器人回复慢。机器人回复慢有很多原因,也有优化方式&#…...

神经网络 | 基于 CNN 模型实现土壤湿度预测
Hi,大家好,我是半亩花海。在现代农业和环境监测中,了解土壤湿度的变化对于作物生长和水资源管理至关重要。通过深度学习技术,特别是卷积神经网络,我们可以利用过去的土壤湿度数据来预测未来的湿度趋势。本文将使用 Pad…...

江科大STM32 终
目录 SPI协议10.1 SPI简介W25Q64简介10.3 SPI软件读写W25Q6410.4 SPI硬件外设读写W25Q64 BKP备份寄存器、PER电源控制器、RTC实时时钟11.0 Unix时间戳代码示例:读写备份寄存器BKP11.2 RTC实时时钟 十二、PWR电源控制12.1 PWR简介代码示例:修改主频12.3 串…...

《MySQL 简易速速上手小册》第10章:未来趋势和进阶资源(2024 最新版)
文章目录 10.1 MySQL 在云计算和容器化中的应用10.1.1 基础知识10.1.2 重点案例:使用 Python 部署 MySQL 到 Kubernetes10.1.3 拓展案例 1:在 AWS RDS 上部署 MySQL 实例10.1.4 拓展案例 2:使用 Docker 部署 MySQL 10.2 MySQL 和 NoSQL 的整合…...

Stable Diffusion 模型下载:GhostMix(幽灵混合)
文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 GhostMix 是绝对让你惊艳的模型,也是自己认为现在最强的2.5D模型。我认为模型的更新应该是基于现有的画面整体不大变的前提下,提高模型的成…...
django解决Table ‘xx‘ already exists的方法
1,首先看已存在的这个库表结构是什么样的,先让对应的model.py恢复到和他一样的字段 2,删除对应app下的migrations目录里面除__init__.py文件的其他所有文件 3,回到manage.py所在目录执行python manage.py makemigrations 4&#x…...
qt学习:arm摄像头+c调用v412框架驱动+qt调用v412框架驱动 显示摄像头画面
目录 跟内核进行数据通信的函数 编程步骤 c代码 头文件 打开摄像头文件 /dev/videox 获取当前主机上(开发板)摄像头列表信息 设置当前摄像头的画面格式 比如说 设置 采集图像的宽度为640 高度 480 在内核空间中,申请一个缓冲区队列…...

Linux 36.2@Jetson Orin Nano基础环境构建
Linux 36.2Jetson Orin Nano基础环境构建 1. 源由2. 步骤2.1 安装NVIDIA Jetson Linux 36.2系统2.2 必备软件安装2.3 基本远程环境2.3.1 远程ssh登录2.3.2 samba局域网2.3.3 VNC远程登录 2.4 开发环境安装 3. 总结 1. 源由 现在流行什么,也跟风来么一个一篇。当然&…...

牛客网SQL264:查询每个日期新用户的次日留存率
官网链接: 牛客每个人最近的登录日期(五)_牛客题霸_牛客网牛客每天有很多人登录,请你统计一下牛客每个日期新用户的次日留存率。 有一个登录(login。题目来自【牛客题霸】https://www.nowcoder.com/practice/ea0c56cd700344b590182aad03cc61b8?tpId82 …...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...

云原生安全实战:API网关Envoy的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口,负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

基于小程序老人监护管理系统源码数据库文档
摘 要 近年来,随着我国人口老龄化问题日益严重,独居和居住养老机构的的老年人数量越来越多。而随着老年人数量的逐步增长,随之而来的是日益突出的老年人问题,尤其是老年人的健康问题,尤其是老年人产生健康问题后&…...

开源项目实战学习之YOLO11:12.6 ultralytics-models-tiny_encoder.py
👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 ultralytics-models-sam 1.sam-modules-tiny_encoder.py2.数据处理流程3.代码架构图(类层次与依赖)blocks.py: 定义模型中的各种模块结构 ,如卷积块、残差块等基础构建…...