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 …...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
