JWT令牌:实现安全会话跟踪与登录认证的利器
摘要:本文深入探讨了JWT令牌在实现会话跟踪和登录认证方面的应用,详细介绍了JWT令牌的概念、组成、生成与校验方法,以及在实际案例中如何通过JWT令牌进行会话跟踪和登录认证的具体实现步骤,为系统的安全认证机制提供了全面且深入的技术指导。
关键词:JWT令牌;会话跟踪;登录认证;生成与校验
参考资料:黑马程序员day12 完整项目请从第10天开始看
一、引言
在基于令牌技术实现会话追踪的背景下,本文着重介绍功能强大的JWT令牌,它作为用户身份标识,以字符串形式存在。接下来将详细阐述JWT令牌的相关知识及在项目中的具体应用。
二、JWT令牌
2.1 介绍
JWT,全称JSON Web Token,官网为https://jwt.io/ 。它定义了一种简洁且自包含的格式,用于在通信双方以json数据格式安全传输信息,凭借数字签名确保信息可靠。
- 简洁性:JWT表现为简单字符串,可在请求参数或请求头中直接传递。
- 自包含性:虽看似随机字符串,但可按需求在其中存储自定义数据,如用户相关信息。本质上,JWT是对原始json数据格式进行安全封装,实现通信双方的安全信息传输。
JWT令牌由三部分组成,各部分间以英文点号分隔:
- Header(头):记录令牌类型、签名算法等信息,例如:{“alg”:“HS256”,“type”:“JWT”} 。
- Payload(有效载荷):携带自定义信息、默认信息等,例如:{“id”:“1”,“username”:“Tom”} 。
- Signature(签名):用于防止Token被篡改,确保安全性。它通过将header、payload与指定秘钥结合,运用指定签名算法计算得出。签名机制使得JWT令牌极为安全可靠,一旦令牌中任何部分被篡改,校验时便会失败。
生成JWT令牌时,会对JSON格式数据进行base64编码。Base64是基于64个可打印字符表示二进制数据的编码方式,使用的字符包括A - Z、a - z、0 - 9、加号、斜杠,共64个字符,另加等号作为补位符号。需注意,Base64是编码方式,并非加密方式。
JWT令牌典型应用场景为登录认证,流程如下:
- 浏览器发起登录请求,访问登录接口,若登录成功,生成JWT令牌并返回给前端。
- 前端接收JWT令牌后存储,后续每次请求将其携带至服务端。
- 服务端统一拦截请求,判断是否携带令牌。若无令牌,拒绝访问;若有令牌,校验其有效性,有效则放行处理请求。
2.2 生成和校验
为在Java代码中生成和校验JWT令牌,首先需引入JWT依赖:
<!-- JWT依赖-->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
引入依赖后,可借助工具类Jwts提供的API完成操作。
- 生成JWT代码实现:
@Test
public void genJwt(){Map<String,Object> claims = new HashMap<>();claims.put("id",1);claims.put("username","Tom");String jwt = Jwts.builder().setClaims(claims) //自定义内容(载荷) .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法 .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期 .compact();System.out.println(jwt);
}
运行上述测试方法,输出的结果即为生成的JWT令牌。可将令牌复制至JWT官网,粘贴于Encoded位置,自动解析令牌。解析后,第一部分显示所用签名算法为HS256;第二部分为自定义数据及设置的过期时间(exp),因前两部分采用base64编码,可直接解码;第三部分由签名算法计算得出,无法直接解析。https://jwt.io/#debugger-io

校验JWT令牌(解析生成的令牌):
@Test
public void parseJwt(){Claims claims = Jwts.parser().setSigningKey("itheima")//指定签名密钥(必须保证和生成令牌时使用相同的签名密钥) .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjcyNzI5NzMwfQ.fHi0Ub8npbyt71UqLXDdLyipptLgxBUg_mSuGJtXtBk").getBody();System.out.println(claims);
}
运行该测试方法,若解析过程未报错,说明解析成功,可看到解析出的id和过期时间。若篡改令牌(如修改header中的数字),解析时会报错,表明JWT令牌被篡改。此外,修改生成令牌时设置的过期时间,过期后再解析也会报错,说明JWT令牌过期后失效。
使用JWT令牌时需注意:
- JWT校验所用签名秘钥必须与生成JWT令牌时的秘钥配套。
- 若JWT令牌解析校验报错,则表明令牌被篡改或已失效,即令牌非法。
2.3 登录下发令牌
完成JWT令牌生成和校验的基础学习后,着手在案例中运用JWT令牌技术跟踪会话,主要包含生成令牌和校验令牌两步。首先实现登录成功后生成JWT令牌并返回给前端。
查看登录接口文档的响应数据部分可知,登录成功后系统下发JWT令牌,后续请求需在请求头header中以“token”为名称,携带登录时下发的JWT令牌。若检测到用户未登录,返回固定错误信息。
实现步骤:
- 引入JWT工具类:在项目工程下创建
com.itheima.utils包,并将提供的JWT工具类复制到该包下。 - 登录完成后,调用工具类生成JWT令牌并返回
JWT工具类
public class JwtUtils {private static String signKey = "itheima";//签名密钥private static Long expire = 43200000L; //有效时间/*** 生成JWT令牌* @param claims JWT第二部分负载 payload 中存储的内容* @return*/public static String generateJwt(Map<String, Object> claims){String jwt = Jwts.builder().addClaims(claims)//自定义信息(有效载荷).signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部).setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间.compact();return jwt;}/*** 解析JWT令牌* @param jwt JWT令牌* @return JWT第二部分负载 payload 中存储的内容*/public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey)//指定签名密钥.parseClaimsJws(jwt)//指定令牌Token.getBody();return claims;}
}
登录成功,生成JWT令牌并返回
@RestController
@Slf4j
public class LoginController {//依赖业务层对象@Autowiredprivate EmpService empService;@PostMapping("/login")public Result login(@RequestBody Emp emp) {//调用业务层:登录功能Emp loginEmp = empService.login(emp);//判断:登录用户是否存在if(loginEmp !=null ){//自定义信息Map<String , Object> claims = new HashMap<>();claims.put("id", loginEmp.getId());claims.put("username",loginEmp.getUsername());claims.put("name",loginEmp.getName());//使用JWT工具类,生成身份令牌String token = JwtUtils.generateJwt(claims);return Result.success(token);}return Result.error("用户名或密码错误");}
}
签名算法大致分类
对称加密算法
- HS256(HMAC with SHA - 256):使用 HMAC(Hash - based Message Authentication Code)算法结合 SHA - 256 哈希函数。在使用 HS256 算法时,服务器端和客户端共享一个相同的密钥(secret)。服务器使用该密钥和 HS256 算法对头部和载荷进行签名生成
JWT。客户端收到 JWT 后,使用相同的密钥和算法重新计算签名,并与 JWT 中的签名进行对比,若一致则说明 JWT 未被篡改。 - HS384(HMAC with SHA - 384):类似于 HS256,只是使用了 SHA - 384 哈希函数,提供更高的安全性,但计算成本也相对较高。
- HS512(HMAC with SHA - 512):使用 SHA - 512 哈希函数,安全性更高,但计算开销也更大,适用于对安全性要求极高的场景。
非对称加密算法
- RS256(RSA Signature with SHA - 256):基于 RSA(Rivest - Shamir - Adleman)非对称加密算法和 SHA - 256 哈希函数。服务器使用私钥对头部和载荷进行签名生成 JWT,客户端使用对应的公钥来验证签名。这种方式无需在客户端和服务器之间共享密钥,提高了安全性,常用于分布式系统或对安全性要求较高的场景。
- RS384(RSA Signature with SHA - 384):使用 RSA 算法结合 SHA - 384 哈希函数。
- RS512(RSA Signature with SHA - 512):使用 RSA 算法结合 SHA - 512 哈希函数。
椭圆曲线算法
- ES256(Elliptic Curve Signature with SHA - 256):基于椭圆曲线密码学(ECC)和 SHA - 256 哈希函数。与 RSA 相比,椭圆曲线算法在相同的安全强度下,密钥长度更短,计算速度更快,适用于对性能要求较高且对安全性有一定要求的移动设备或资源受限的环境。
- ES384(Elliptic Curve Signature with SHA - 384):使用椭圆曲线算法结合 SHA - 384 哈希函数。
- ES512(Elliptic Curve Signature with SHA - 512):使用椭圆曲线算法结合 SHA - 512 哈希函数。
相关文章:
JWT令牌:实现安全会话跟踪与登录认证的利器
摘要:本文深入探讨了JWT令牌在实现会话跟踪和登录认证方面的应用,详细介绍了JWT令牌的概念、组成、生成与校验方法,以及在实际案例中如何通过JWT令牌进行会话跟踪和登录认证的具体实现步骤,为系统的安全认证机制提供了全面且深入的…...
VS 中Git 中本地提交完成,没有推送,修改的内容如何还原
在 Visual Studio 中撤销本地提交但未推送的修改,可以通过以下方法实现: 一、保留修改内容(仅撤销提交记录) 使用 git reset --soft 在 VS 的 Git 终端中执行: git reset --soft HEAD~1作用:撤销最后一次提…...
springboot+tabula解析pdf中的表格数据
场景 在日常业务需求中,往往会遇到解析pdf数据获取文本的需求,常见的做法是使用 pdfbox 来做,但是它只适合做一些简单的段落文本解析,无法处理表格这种复杂类型,因为单元格中的文本有换行的情况,无法对应到…...
Ubuntu18.04 ROS Melodic安装
环境配置:Ubuntu18.04 ROS Melodic安装_ubuntu18.04安装ros melodic-CSDN博客 1 设置安装源 为了安装ROS Melodic,首先需要在Ubuntu 18.04 LTS上添加安装源到source.list,方法如下: 国外的: sudo sh -c echo "deb http://…...
阿里FPGA XCKU3P开箱- 25G 光纤
阿里FPGA XCKU3P开箱 - Hello-FPGA - 博客园 25G 光纤 板子有2个SFP的光纤接口,最大支持25G速率,使用ibert 进行验证,SFP在BANK227的GTY 接口。 ibert 配置如下: 测试 测试符合预期,确认了SFP的具体位置 和 支持的速…...
ArrayList vs LinkedList,HashMap vs TreeMap:如何选择最适合的集合类?
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 在 Java 开发中,集合类的选择直接影响程序的性能和代码的可维护性。不同的数据结构适用于不同的场景,盲目使用可能导致内存浪费、性能…...
uniapp的h5,打开的时候,标题会一闪而过应用名称,再显示当前页面的标题
问题: 微信小程序,通过webview打开了uniapp创建的h5,但是打开h5时,会先显示h5的应用名称,然后才切换为该页面的标题。 过程: 查过很多资料,有说修改应用名称,有说设置navigationS…...
玩转Docker | 使用Docker搭建Van-Nav导航站
玩转Docker | 使用Docker搭建Van-Nav导航站 前言一、Van-Nav介绍van-nav 简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署Van-Nav服务下载镜像创建容器检查容器状态检查服务端口安全设置四、访问Van-Nav应用访问Van-Nav首页登录后台管理五、添…...
Margin和Padding在WPF和CSS中的不同
CSS和WPF中 margin 与 padding 在方向上的规定基本一致,但在使用场景和一些细节上有所不同。 CSS - 方向规定: margin 和 padding 属性可以分别指定上、右、下、左四个方向的值。例如 margin:10px 20px 30px 40px; 表示上外边距为10px、右外边距为20…...
.NET Core DI(依赖注入)的生命周期及应用场景
在.NET中,依赖注入(DI,Dependency Injection)是一种设计模式,它通过将依赖关系注入到类中,而不是让类自己创建依赖项,来降低类之间的耦合度。这使得代码更加模块化、灵活和易于测试。在.NET中&a…...
新技术学习方法
新技术学习方法 学习新技术的路线需要结合系统性规划与实践验证,以下是基于行业经验和学习科学整理的高效路径框架,适用于编程语言、开发框架、前沿技术等领域: 一、明确学习目标与动机(战略层) 场景化需求分析 明确…...
内网dns权威域名服务器搭建
目录 一、背景 二、dns简介 1、dns服务器类型 1、缓存域名服务器 2、主域名服务器 3、从域名服务器 2、dns解析过程 1、递归查询 2、迭代查询: 3、dns服务器类型 1、根域名服务器 2、顶级域名服务器 顶级域名可分为两类 顶级域名服务器的重要性体现在…...
爱普生SG2520VGN差分晶振5G基站的时钟解决方案
在 5G 通信时代,数据流量呈爆发式增长,5G 基站作为信号的核心中转枢纽,承载着前所未有的数据传输与处理重任。从海量的物联网设备连接,到高速移动用户的数据交互,每一个环节都对基站的性能提出了严苛要求。而精准稳定的…...
Linux中设置文件开机自启
###方法有很多,这里只分享一个systemd的方法 1.创建service文件 在/etc/systemd/system/下创建,自己命名,后缀是.service 创建方式有两种: 进入/etc/systemd/system创建,创建后使用sudo vim编辑使用sudo nano /etc/…...
C# 基类型和派生类型之间的转型
1.什么是基类型和派生类 基类型:父类,所有子类都继承自它。 派生类型:子类,继承了父类的属性和方法,还可以添加自己的新功能。 例子: class Animal { }//基类型 class Dog : Animal { }//派生类型 这…...
AWTK-MVVM 如何让多个View复用一个Model记录+关于app_conf的踩坑
前言 有这么一个业务,主界面点击应用窗口进入声纳显示界面,声纳显示界面再通过按钮进入菜单界面,菜单界面有很多关于该声纳显示界面的设置项,比如量程,增益,时间显示,亮度,对比度等…...
MySQL视图相关
视图基础概念 定义:视图是一条SELECT语句执行后返回的结果集,是对若干基本表的引用,是一张虚表,不存储具体数据。特性:依赖基本表,基本表数据改变时视图数据也随之改变;限定条件下可进行增删改…...
blender 超逼真角色daz 纹理材质 humanpro插件
https://www.youtube.com/KhanhVo-zp9lh/featured https://superhivemarket.com/products/humanpro https://superhivemarket.com/products/humanpro HUMANPRO 插件 - BLENDER HumanPro 是一款专为帮助用户轻松快速地创建高度精细逼真的人体皮肤纹理和复杂皱纹而设计的插件…...
C++简易日志
文章目录 main.cppLog.hLog.cppClassAuxMacro.hSingleton.h main.cpp #include "Log.h"int main() {LogInfo << "main start";int i 1;double d 3.14;LogInfo << "i " << i << ", d " << d;getcha…...
kotlin音乐之自定义唱片组件(简单版本)
代码地址 import android.animation.ObjectAnimator import android.animation.ValueAnimator import android.content.Context import android.os.Binder import android.util.AttributeSet import android.view.animation.LinearInterpolator import androidx.appcompat.widg…...
Redis 版本变更的变化
Redis 版本变更的变化 以下是 Redis 主要版本的清单及其核心功能变化的梳理,按时间顺序整理关键版本演进 8版本没有整理: Redis 1.0 (2009) 初始版本:发布首个稳定版本,支持基本键值存储。 核心特性: 支持字符串&…...
flink扫盲-调整checkpoint的时间会影响原来的state数据吗
一、核心结论 原 State 数据仍可用 只要作业的 拓扑结构(DAG) 和 状态类型(StateDescriptor) 未发生变更,旧的 Checkpoint 依然有效。Checkpoint 间隔调整仅影响 新生成的 Checkpoint…...
文本纠错WPS插件:提升文档质量的利器
文本纠错WPS插件:提升文档质量的利器 引言 在数字化办公日益普及的今天,文档的质量直接影响到我们的工作效率和形象。一个错别字或标点错误,可能就会让我们的专业形象大打折扣。今天,我要向大家介绍一款强大的WPS插件——文本纠…...
多光谱相机与高光谱相机的区别
多光谱相机与高光谱相机均属于光谱成像设备,但两者在光谱分辨率、波段数量、数据维度及应用场景上存在显著差异。以下是详细的对比分析: 一、核心差异对比 二、工作原理差异 多光谱相机 波段选择:根据目标物特性预设特定…...
MVCC详细介绍及面试题
目录 1.什么是mvcc? 2.问题引入 3. MVCC实现原理? 3.1 隐藏字段 3.2 undo log 日志 3.2.1 undo log版本链 3.3 readview 3.3.1 当前读 编辑 3.3.2 快照读 3.3.3 ReadView中4个核心字段 3.3.4 版本数据链访问的规则(了解&#x…...
电商企业如何实现流程精细化?日事清「标准化+可视化+自动化」全流程管理实战解析
电商企业在业务快速发展中,往往会遇到如下问题: 1、店铺多款产品需要上新维护,但工作重点往往不清晰,员工经常忘记,没做也不当回事; 2、员工做事经常错漏细节,犯低级错误; 3、人员…...
威锋VL822-Q7T10GHUB芯片适用于扩展坞显示器
一、概述 VL822-Q7T是VIA Lab(威盛电子旗下专注于USB相关技术研发的子公司)精心打造的一款高性能USB 3.1 Gen2集线器控制器芯片。在当今数字化时代,USB接口作为设备连接与数据传输的核心通道,其性能与稳定性至关重要。VL822-Q7T凭…...
交换机与路由器的默契配合:它们的联系与区别
交换机与路由器的默契配合:它们的联系与区别 一. 交换机与路由器的基本功能1.1 交换机的功能1.2 路由器的功能 二. 交换机和路由器的区别三. 交换机和路由器的联系3.1 数据转发的协作3.2 网络分段与分隔3.3 协同工作提供互联网接入 四. 交换机和路由器的联合应用场景…...
Git提交规范及最佳实践
Git 提交规范通常是为了提高代码提交的可读性、可维护性和自动化效率(如生成 ChangeLog)。以下是常见的 Conventional Commits 规范,结合社区最佳实践总结而成: 1. 提交格式 每次提交的 commit message 应包含三部分:…...
Ubuntu 常用命令行指令
1. 文件与目录操作 命令作用示例ls列出目录内容ls -l(详细列表)cd切换目录cd ~/Documentspwd显示当前目录路径pwdmkdir创建目录mkdir new_folderrm删除文件rm file.txtrm -r递归删除目录rm -r old_dircp复制文件cp file.txt backup/mv移动/重命名文件mv…...
