JWT的学习
1、HTTP无状态及解决方案
HTTP一种是无状态的协议,每次请求都是一次独立的请求,一次交互之后就是陌生人。
以CSDN为例,先登录一次,然后浏览器退出,这个时候在进入CSDN,按理说服务器是不知道你已经登陆了,所以需要你重新登录,但实际却是再次点进来之后,仍然保持登录状态。
这是因为解决了HTTP无状态这个问题,解决方式有很多:
①使用Session和Cookie,将 无状态 变为 有状态
第一次请求时,服务器会自动记录一个SessionId,然后把SessionId返回给浏览器。再次发起请求时,浏览器就会携带SessionId,而服务器就可以根据SessionId,去查询会话信息(session)。
服务器可以往会话里保存用户信息

浏览器会自动保存SessionId
![]()
Session弊端:Session和Cookie适用于单机环境,默认情况下会话信息(session)是保存在服务器内存中,用户量大的话,服务器内存压力大。如果生产是集群环境,就没办法保证浏览器的请求每一次都传到有会话信息的那一台服务器。
这种也好解决,把会话信息存到Redis里,每次访问,服务器根据SessionId,去Redis拿会话信息(SpringBoot实现了这个功能,引入【spring-session-data-redis】依赖包,做一些设置,就会自动将会话信息交给Redis管理),这样做服务器的内存压力也就会见。
②使用Token
在登录时,生成一个Token放入Redis,之后把token返回给浏览器。浏览器发起其他请求时,携带这个token,服务器再去Redis看这个Token是否失效之类的。
③使用JWT
使用JWT和使用Token很像,但JWT不需要存储到Redis,就能通过验签,知道用户信息是否伪造、用户登录状态是否过期等等。
2、JWT的基本介绍
JWT官网地址:https://jwt.io/
JWT,全称JSON WEB TOKEN,是一种JSON格式的Web应用令牌,它是基于令牌去做认证。
什么是令牌,举个例子,古代调兵用的虎符,这就相当于是令牌,有了虎符,才能调兵。而令牌也是,有了令牌,才能访问后端接口。
以下是官网介绍

大致就是JWT能够通过HMAC算法(默认算法),或者通过RSA、ECDSA算法生成数字签名(Signature)。
JWT令牌的组成

JWT由三部分组成:Header(头)、Payload(负载)、Signature(签名),三部分用 "." 进行分隔
Header
两部分组成:令牌的类型是什么,签名(Signature)使用什么算法。
从官网复制的例子,表示令牌的类型是JWT,算法是 HMAC-SHA256
{"alg": "HS256","typ": "JWT" }
Header的JSON串经过Base64编码就转换成 "x.y.z" 的 "x"部分
Payload
负载有七个默认字段
iss:发行人
exp:到期时间
sub:主体
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
官方样例如下:name 和 admin为自定义的字段
{"sub": "1234567890","name": "John Doe","admin": true
}
负载里面可以放自定义字段,这部分内容也是通过Base64编码变成"x.y.z"部分的"y"部分,可以通过Base64解码,拿到里面的信息。所以,官方也推荐不要往负载里存放敏感信息,比如密码之类的,除非想故意被攻击。
Signature
官方提供的例子如下,可以看见,签名是通过前两部分(Header 和 Payload)base64编码之后的字符串拼接成一个新的字符串,以及指定一个密钥(secret),并使用Header里指定的算法生成的签名。因此,密钥是一定不能暴露出去的。
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
假如攻击者对前两部分进行随意修改,并冒充前端发起请求。后端每次验签的时候,都会根据前两部分内容,加上密钥(secret),再去生成一次签名,而由于攻击者修改了内容,所以生成的签名肯定和传来的签名不匹配,这就说明被篡改了,从而验签失败。

3、JWT的优缺点
优点
1、JWT生成的令牌保存在客户端(前端),服务端不会保存令牌,减少了服务器内存的损耗。
2、易扩展,负载中可以保存自定义的信息。
3、使用强密钥生成签名时,JWT提供了很好的安全性。
4、使用JWT,HTTP仍是无状态的,和Session、Cookie的方式正好相反,JWT不需要在服务器存储会话信息,非常适合集群环境。
缺点
1、JWT 本身不支持会话管理,不能主动使令牌失效。假如用户修改了密码,这个时候肯定要重新登录,原先的JWT令牌按理就应该失效,但是,由于没有到令牌指定的过期时间,所以原先的令牌仍然是有效的。(可以将令牌存到redis,当修改密码后删除令牌,当令牌没有就强制用户去登录)
2、负载(Payload)中存放过多用户数据时,会影响性能。
4、如何使用JWT
大致流程:用户通过前端页面进行登录,业务校验通过之后,生成一个令牌(JWT),后端将JWT返回给前端,前端进行保存。之后,前端每次访问后端,都必须携带JWT,后端去验证令牌(JWT)的合法性。
①导入JWT依赖
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version>
</dependency>
②编写工具类,生成令牌
前面提到了,JWT令牌由三部分组成,所以创建一个JWT令牌,只要保证有这三部分就可以了
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;public class JWTUtil {//密钥,一般是从配置文件读取private static final String secretKey = "4008123123@#";private static final String algorithm = Algorithm.HMAC256(secretKey).getName();/*** 生成JWT令牌** @return*/public static String generateJwtToken(String userId, String secretKey) {Calendar exp = Calendar.getInstance();//过期时间:当前时间往后推20分钟exp.add(Calendar.MINUTE, 20);System.out.println("过期时间:" + exp.getTime());// HashMap<String, Object> map = new HashMap<String, Object>();
// map.put("alg",algorithm);
// map.put("typ","JWT");String token = JWT.create()//header,即使不写,也会使用默认的推荐算法HS256和JWT令牌类型
// .withHeader(map).withExpiresAt(exp.getTime()) //默认的负载字段,设置过期时间.withClaim("userId", userId) //负载---自定义字段.withClaim("username", "UMR123") //负载---自定义字段.sign(Algorithm.HMAC256(secretKey));System.out.println(token);return token;}/*** 验签(验证JWT令牌的合法性)** @param jwtToken* @param secretKey* @return 用来获取令牌信息*/public static DecodedJWT verifyToken(String jwtToken, String secretKey) {//生成验证对象JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secretKey)).build();//如果验证没问题,就可以获取到负载信息,如果签名有问题(签名不一致,令牌过期),就会报错DecodedJWT verify = jwtVerifier.verify(jwtToken);System.out.println("负载(Payload)经过base64解码:" + new String(Base64.getDecoder().decode(verify.getPayload())));System.out.println("userId信息:" + verify.getClaim("userId").asString());System.out.println("username信息:" + verify.getClaim("username").asString());System.out.println("令牌过期时间:" + verify.getExpiresAt());return verify;}public static void main(String[] args) {//生成令牌String jwtToken = generateJwtToken("user123", secretKey);System.out.println();verifyToken(jwtToken, secretKey);}
}
控制台打印结果如下:

服务端生成JWT令牌之后,客户端在请求其他接口时,请求头新增Authorization字段,放入JWT信息
Authorization: Bearer <token>

都是对数据完整性和用户身份进行校验,什么时候直接使用算法生成签名,什么时候使用JWT?
当需求没有要求过期时间,就可以使用直接使用算法,反之,用JWT令牌是最好的。
相关文章:
JWT的学习
1、HTTP无状态及解决方案 HTTP一种是无状态的协议,每次请求都是一次独立的请求,一次交互之后就是陌生人。 以CSDN为例,先登录一次,然后浏览器退出,这个时候在进入CSDN,按理说服务器是不知道你已经登陆了&…...
elasticsearch是哪家的
Elasticsearch:数据搜索与分析的领航者 在当今这个信息爆炸的时代,快速且准确地处理海量数据成为了众多企业和组织追求的目标。而Elasticsearch正是在这个背景下脱颖而出的一款强大的开源搜索引擎。它是由位于美国加利福尼亚州的Elastic公司所开发和维护…...
《A++ 敏捷开发》- 18 软件需求
需求并不是关于需求 (Requirements are not really about requirements) 大家去公共图书馆寄存物品,以前都是扫二维码开箱,有些图书馆升级了使用指纹识别。 “是否新方法比以前好?”我问年轻的开发人员。 “当然用指纹识别好。新技术&#x…...
计算机网络:计算机网络的组成和功能
计算机网络的组成: 计算机网络的工作方式: 计算机网络的逻辑功能; 总结: 计算机网络的功能: 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点(计算机或设备&…...
Upload-Labs-Linux 1-20
前端校验绕过:pass 01 两种思路:1.通过抓包,修改后缀 2.前端禁用js绕过前端后缀检验 首先写一个木马,改为图片格式GIF89a<?php eval($_POST[cmd])?>抓包之后改为PHP格式: 使用蚁剑连接木马,第一次尝…...
Compose笔记(八)--权限
这一节主要了解一下Compose中权限的申请,其中主要用到accompanist-permissions这个权限库,它是一个简化的Android Compose 中权限管理的库,如下使用: 栗子: 依赖添加 dependencies {implementation("com.google.accompani…...
单例模式:确保一个类只有一个实例
目录 引言 1. 单例模式的核心思想 2. 单例模式的实现方式 2.1 饿汉式单例 2.2 懒汉式单例 2.3 线程安全的懒汉式单例 2.4 双重检查锁定(Double-Checked Locking) 2.5 静态内部类实现单例 2.6 枚举实现单例 3. 单例模式的使用场景 4. 单例模式…...
推荐一个好用的在线文本对比网站 - diffchecker
推荐网址:https://www.diffchecker.com UI设计也很不错,响应也很快,广告少 生成的对比还可以生成在线链接:(点击右上角“分享”) 可设置过期时间等 我生成的示例:https://www.diffchecker.c…...
学习第八十五行
[capture](parameters) -> return_type {// function body }capture: 捕获列表,指定如何捕获周围作用域中的变量。parameters: 参数列表,与普通函数类似。return_type: 返回类型,可以省略,编译器会自动推断。function body: 函…...
基于Django创建一个WEB后端框架(DjangoRestFramework+MySQL)流程
一、Django项目初始化 1.创建Django项目 Django-admin startproject 项目名 2.安装 djangorestframework pip install djangorestframework 解释: Django REST Framework (DRF) 是基于 Django 框架的一个强大的 Web API 框架,提供了多种工具和库来构建 RESTf…...
【Python 2D绘图】Matplotlib绘图(统计图表)
【Python 2D绘图】Matplotlib绘图(统计图表) 1. 概述1.1 简介1.2 安装1.3 导入1.4 保存1.5 数据来源1.5.1 Numpy ndarray1.5.2 Pandas DataFrame 1.6 中文显示 2. 基础样式2.1 颜色2.1.1 简称2.1.2 全称 2.2 布局2.2.1 Matplotlib 画布划分2.2.2 绘制子图…...
vue3框架的响应式依赖追踪机制
当存在一个响应式变量于视图中发生改变时会更新当前组件的所以视图显示,但是没有视图中不写这个响应式变量就就算修改该变量也不会修改视图,这是为什么?我们能否可以理解宽泛的理解为vue组件的更新就是视图的更新,单当视图中不存在…...
.Net 6 上传文件接口 文件大小报错整体配置
/// <summary>/// 上传文件/// </summary>/// <param name"file"></param>/// <returns></returns>[HttpPost("UploadifyFile")][RequestSizeLimit(2000 * 1024 * 1024)] // 设置最大请求体大小为 100MBpublic async …...
Git基础之工作原理
基础概念 git本地有三个工作区域,工作目录 Working Directory,暂存区Stage/Index和资源区Repository/Git Directory,如果在加上远程的git仓库就是四个工作区域 四个区域与文件交换的命令之间的关系 WorkSpace:工作区,就…...
小程序 wxml 语法 —— 41列表渲染 - 进阶用法
这一节讲解列表渲染的两个进阶用法: 如果需要对默认的变量名和下标进行修改,可以使用 wx:for-item 和 wx:for-item: 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…...
ElasticSearch 入门教程
ElasticSearch 入门教程 ElasticSearch 是一个分布式、可扩展的搜索和分析引擎,基于 Apache Lucene 构建,支持全文检索、结构化查询和聚合分析。本教程将带你深入了解 ElasticSearch 的核心概念、安装配置、常见操作,并提供示例代码…...
用Python写一个算24点的小程序
一、运行界面 二、显示答案——递归介绍 工作流程: 1. 基本情况:函数首先检查输入的数字列表 nums 的长度。如果列表中只剩下一个数字,它会判断这个数字是否接近 24(使用 abs(nums[0] - 24) < 1e-10 来处理浮点数精度问题&…...
分布式网络
分布式网络(Distributed Network)指的是一种计算机网络架构,其中计算资源(计算、存储、数据处理等)分布在多个物理或逻辑上的节点上,而不是集中在单一的服务器或数据中心中。这种架构的主要目标是提高系统的…...
忘记dedecms后台超级管理员账号和密码的解决方案
解决方案: 方案一、数据库修改: 1、前提是您能登录到数据库后台,登录MySQL数据库管理工具(如phpMyAdmin) 2、打开数据库中的 dede_admin 表,找到管理员记录,将 pwd 字段的值改成 f297a57a5a7…...
【Linux学习笔记】Linux基本指令分析和权限的概念
【Linux学习笔记】Linux基本指令分析和权限的概念 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】Linux基本指令分析和权限的概念前言一. 指令的分析1.1 alias 指令1.2 grep 指令1.3 zip/unzip 指…...
告别死记硬背!信息系统项目管理师(高项)思维导图活用法:从考前3个月到考前一天的全周期规划
信息系统项目管理师备考革命:用思维导图构建你的动态知识引擎 备考信息系统项目管理师(高项)的过程,常常让考生陷入两难困境:一方面要掌握庞杂的知识体系,另一方面又要应对实际工作中的时间压力。传统死记硬…...
从ReVeal到实战:基于图神经网络的智能漏洞检测技术演进与落地思考
1. 图神经网络在漏洞检测中的崛起 第一次接触代码漏洞检测领域时,我被传统方法的繁琐流程震惊了。记得当时需要手动定义数百条规则来检测缓冲区溢出漏洞,每次遇到新漏洞类型就得加班加点补充规则。直到2018年遇到ReVeal论文,才发现图神经网络…...
从零搭建中文资源媒体中心:Kodi中文插件库完全指南
从零搭建中文资源媒体中心:Kodi中文插件库完全指南 【免费下载链接】xbmc-addons-chinese Addon scripts, plugins, and skins for XBMC Media Center. Special for chinese laguage. 项目地址: https://gitcode.com/gh_mirrors/xb/xbmc-addons-chinese 你是…...
基于FLUX.2-klein-base-9b-nvfp4的Java后端服务集成指南
基于FLUX.2-klein-base-9b-nvfp4的Java后端服务集成指南 最近在做一个内容创作平台的后台重构,产品经理提了个需求,希望用户上传的草图或者简单的线框图,能自动转换成更精美的概念图。这要是放在以前,要么找设计师手动处理&#…...
阿里小云KWS模型在STM32平台上的轻量化部署
阿里小云KWS模型在STM32平台上的轻量化部署 1. 为什么要在STM32上跑语音唤醒 很多开发者第一次听说要在STM32这种资源受限的微控制器上部署语音唤醒模型时,第一反应往往是:这可能吗?毕竟STM32通常只有几百KB的Flash和几十KB的RAM࿰…...
LiuJuan20260223Zimage网络安全攻防演练:模拟攻击与智能防御
LiuJuan20260223Zimage网络安全攻防演练:模拟攻击与智能防御 最近在捣鼓一个挺有意思的AI工具,叫LiuJuan20260223Zimage。这名字有点长,但功能确实让人眼前一亮。它不像那些只会聊天或者画图的模型,而是专门针对网络安全这块&…...
别再只用欧氏距离了!用Python+NumPy实战马氏距离异常检测(附卡方分布阈值设定)
用Python实战马氏距离异常检测:从理论到工业级实现 在数据分析领域,距离度量是许多算法的基石。当数据维度升高且特征间存在相关性时,传统的欧氏距离就像用一把没有刻度的尺子测量复杂空间——它无法捕捉变量间的相互作用。想象一下金融交易监…...
极简纯净音乐体验:铜钟音乐平台的高效使用指南
极简纯净音乐体验:铜钟音乐平台的高效使用指南 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特!(密码重置功能已回归) 项目地址: https://gitcode.com/GitHub_Trending/to/t…...
Phi-3-vision-128k-instruct创意编程:用JavaScript构建交互式图像故事生成器
Phi-3-vision-128k-instruct创意编程:用JavaScript构建交互式图像故事生成器 1. 引言:当AI创意遇上前端交互 想象这样一个场景:用户上传一张随手拍的照片,通过简单的滑块调整和风格选择,几秒钟后就能获得一个与图片内…...
从H5到uni-app:迁移‘滚动菜单高亮’功能时,我踩过的3个关键差异点
从H5到uni-app:迁移滚动菜单高亮功能的三大思维转换 第一次在uni-app里实现滚动菜单高亮效果时,我差点把键盘摔了——那些在H5里信手拈来的document.querySelector和window.scrollY突然全部失效。这就像习惯右手写字的人突然被要求用左手,明明…...
