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令牌典型应用场景为登录认证,流程如下:

  1. 浏览器发起登录请求,访问登录接口,若登录成功,生成JWT令牌并返回给前端。
  2. 前端接收JWT令牌后存储,后续每次请求将其携带至服务端
  3. 服务端统一拦截请求,判断是否携带令牌。若无令牌,拒绝访问;若有令牌,校验其有效性,有效则放行处理请求。

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 哈希函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mybtis和Mybatis-Plus区别

MyBatis 和 MyBatis-Plus 是 Java 中常用的持久层框架&#xff0c;MyBatis-Plus 是在 MyBatis 基础上增强的工具包&#xff0c;让开发更便捷、高效。下面是两者主要的区别&#xff1a; ✅ 核心区别总结&#xff1a; 特性MyBatisMyBatis-Plus配置复杂度需要手写大量 XML 或注解…

JavaScript 性能优化实战

一、代码执行效率优化 1. 减少全局变量的使用 全局变量在 JavaScript 中会挂载在全局对象(浏览器环境下是window,Node.js 环境下是global)上,频繁访问全局变量会增加作用域链的查找时间。 // 反例:使用全局变量 var globalVar = example; function someFunction() {con…

学习笔记十六——Rust Monad从头学

&#x1f9e0; 零基础也能懂的 Rust Monad&#xff1a;逐步拆解 三大定律通俗讲解 实战技巧 &#x1f4e3; 第一部分&#xff1a;Monad 是什么&#xff1f; Monad 是一种“包值 链操作 保持结构”的代码模式&#xff0c;用来处理带上下文的值&#xff0c;并方便连续处理。 …

PL/SQL登录慢,程序连接Oracle 提示无法连接或无监听

PL/SQL登录慢&#xff0c;程序连接Oracle 提示无法连接或无监听 错误提示&#xff1a;ORA-12541: TNS: 无监听程序 的解决办法&#xff0c; 现象&#xff1a;PL/SQL登录慢&#xff0c;程序连接Oracle 提示无法连接或无监听 监听已经正常开起&#xff0c;但还是PL/SQL登录慢或…

Windows10,11账户管理,修改密码,创建帐户...

在这里&#xff0c;我们使用微软操作系统的一款工具:netplwiz 它可以非常便捷的管理用户账户. 一:修改密码(无需现在密码) 01修改注册表 运行命令&#xff1a;regedit 在地址栏输入&#xff1a; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Passwor…

电脑 BIOS 操作指南(Computer BIOS Operation Guide)

电脑 BIOS 操作指南 电脑的BIOS界面&#xff08;应为“BIOS”&#xff09;是一个固件界面&#xff0c;允许用户配置电脑的硬件设置。 进入BIOS后&#xff0c;你可以进行多种设置&#xff0c;具体包括&#xff1a; 1.启动配置 启动顺序&#xff1a;设置从哪个设备启动&#x…

iOS 冷启动时间监控:启动起点有哪些选择?

⏱️ iOS 冷启动时间监控&#xff1a;启动起点有哪些选择&#xff1f; 作者&#xff1a;侯仕奇 来源&#xff1a;sqi.io 在监控 iOS 冷启动性能时&#xff0c;一个关键问题是&#xff1a;如何精确记录 App 冷启动的开始时间&#xff1f; 本文将对不同的“冷启动起点”监控方式…

onlyoffice关闭JWT后依然报错如何解决?

onlyoffice关闭JWT后依然报错如何解决&#xff1f; 一、部署方式 我是以docker方式部署的&#xff0c;直接通过环境变量禁用了JWT&#xff0c;命令如下&#xff1a; docker run -d \--name onlyoffice-no-jwt \--restartalways \-p 8069:80 \-e JWT_ENABLEDfalse \onlyoffic…

rk3588 驱动开发(一)字符设备开发

3.字符设备驱动开发 3.1 什么是字符设备驱动 字符设备&#xff1a;就是一个个字节&#xff0c;按照字节流进行读写操作的设备&#xff0c;读写是按照先后顺序的。 举例子&#xff1a;IIC 按键 LED SPI LCD 等 Linux 应用程序调用驱动程序流程&#xff1a; Linux中驱动加载成功…

设计模式 --- 外观模式

外观模式是一种结构型设计模式&#xff0c;为复杂子系统提供​​统一的高层接口​​&#xff0c;通过定义一个外观类来​​简化客户端与子系统的交互​​&#xff0c;降低系统耦合度。这种模式隐藏了子系统的复杂性&#xff0c;将客户端与子系统的实现细节隔离开来&#xff0c;…

我的gittee仓库

日常代码: 日常代码提交https://gitee.com/xinxin-pingping/daily-code 有需要的宝子们可自行读取。

微服务调用中的“大对象陷阱”:CPU飙高问题解析与优化

背景 对几十万条用户历史存量数据写入&#xff0c;且存在大对象的基础上。kafka消费进行消费写mysql超时。导致上游服务调用时异常&#xff0c;CPU飙高异常。 大对象解释 大对象的定义与危害 1. 什么是大对象&#xff1f; JVM 内存分配机制&#xff1a;Java 中对象优先分配…

代码随想录算法训练营day6(字符串)

华子目录 反转字符串思路 反转字符串II思路 替换数字思路 反转字符串 https://leetcode.cn/problems/reverse-string/ 思路 使用双指针&#xff0c;初始化时&#xff0c;left指向下标0的位置&#xff0c;right指向最后一个元素的下标当while left<right时&#xff0c;交换…

Oracle 19c新特性:OCP认证考试与职业跃迁的关键?

在数字化转型的浪潮中&#xff0c;Oracle 19c作为数据库领域的旗舰版本&#xff0c;不仅承载着技术革新的使命&#xff0c;更成为IT从业者职业进阶的“黄金跳板”。无论是企业级应用的高可用性需求&#xff0c;还是云原生架构的快速迭代&#xff0c;Oracle 19c的智能化与多模型…

【MySQL数据库入门到精通】

文章目录 一、SQL分类二、DDL-数据库操作1.查询2.创建数据库3.删除数据库4.使用数据库 三、DDL-表操作1.查询 一、SQL分类 根据功能主要分为DDL DML DQL DCL DDL:Date Definition Language数据定义语言&#xff1a;定义数据库&#xff0c;表和字段 DML:Date Manipulatin Lan…

MCP服务端开发

MCP(Memory, Context, Planning)是一种增强AI系统认知能力的框架,通过整合记忆管理、上下文理解和规划能力,可以显著提升AI系统的表现。下面我将为您开发一个完整的MCP服务端。 概述 我们将使用Python开发一个基于FastAPI的MCP服务端,包含以下核心组件: Memory Manager…

前端:uniapp中uni.pageScrollTo方法与元素的overflow-y:auto之间的关联

在uniapp中&#xff0c;uni.pageScrollTo方法与元素的overflow-y:auto属性之间存在以下关联和差异&#xff1a; 一、功能定位差异 ‌uni.pageScrollTo‌ 属于‌页面级滚动控制‌&#xff0c;作用于整个页面容器‌34。要求页面内容高度必须超过屏幕高度&#xff0c;且由根元素下…

基础知识-指针

1、指针的基本概念 1.1 什么是指针 1.1.1 指针的定义 指针是一种特殊的变量&#xff0c;与普通变量存储具体数据不同&#xff0c;它存储的是内存地址。在计算机程序运行时&#xff0c;数据都被存放在内存中&#xff0c;而指针就像是指向这些数据存放位置的 “路标”。通过指针…

VS远程Linux_CMake项目搭建

VS远程Linux CMake项目搭建 准备工作 远程计算机上安装 gcc: 一个开源的编译器集合, GCC支持多种编程语言的编译&#xff0c;包括C、C、Objective-C、Fortran、Ada、Go、D和Javagdb: GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&#xff0c;主要用于调…

替代升级VMware | 云轴科技ZStack构建山西证券一云多芯云平台

通过云轴科技ZStack Cloud云平台&#xff0c;山西证券打造了敏捷部署、简单运维的云平台&#xff0c;不仅兼容x86、海光、鲲鹏三种异构服务器实现一云多芯&#xff0c;还通过云平台虚拟化纳管模块纳管原有VMware虚拟化资源&#xff0c;并对接第三方集中式存储&#xff0c;在保护…