JWT的基础与使用
JWT(JSON Web Token) 是一种用于在各方之间传输信息的紧凑、安全的方式,常用于身份验证和授权。它以令牌的形式将用户信息编码后传输,可以确保数据的完整性和安全性。
1.JWT的结构
JWT 是一个基于 JSON 的令牌,由三部分组成,通过点号 (.) 分隔:
header.payload.signature
每部分都是经过 Base64Url 编码的字符串,分别对应以下三个部分:
1)Header(头部):
头部包含令牌的元数据,通常包括令牌类型和签名算法。
例子:
| { "alg": "HS256", "typ": "JWT" } |
alg: 签名使用的算法(如 HMAC SHA256)。
typ: 声明令牌类型为 JWT。
2)Payload(有效载荷):
有效载荷包含用户的声明(claims),也就是实际传输的数据。它通常包含身份验证或授权所需的信息。
| { "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022 } |
常见的标准声明:
- iss (issuer):签发者
- sub (subject):面向的用户
- aud (audience):接收的受众
- exp (expiration):过期时间
- iat (issued at):签发时间
- nbf (not before):生效时间
自定义声明:可以根据需求添加任何信息。
3)Signature(签名):
签名用于验证令牌的真实性,并确保令牌在传输过程中没有被篡改。
签名的生成方式:
| HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) |
签名使用头部中声明的算法和一个秘密密钥(secret key)生成。
2.JWT的工作流程
2.1.生成JWT
用户登录后,服务器生成一个包含用户身份信息的 JWT,使用密钥对其进行签名。
2.2.客户端存储JWT
生成的 JWT 会返回给客户端,客户端通常将其存储在浏览器的 localStorage 或 sessionStorage 中,或者存储在 Cookie 中。
2.3.客户端请求时携带JWT
在后续的请求中,客户端将 JWT 附加在请求头的 Authorization 字段中:
| Authorization: Bearer <token> |
2.4.服务器验证JWT
服务器接收到 JWT 后,会使用相同的密钥对签名进行验证,确保令牌的完整性和真实性。
如果 JWT 有效,服务器允许访问资源;如果令牌无效或过期,返回 401 未授权状态。
3.JWT的优势
1)无状态:JWT 是无状态的,所有信息都保存在令牌中,服务器不需要维护会话数据。
2)跨域支持:由于 JWT 不依赖于特定的存储机制,适合跨域认证。
3)紧凑性:JWT 的结构紧凑,便于在 URL、HTTP 请求头等地方传输。
4)灵活性:JWT 可以包含任意声明,支持灵活的身份和权限管理。
4.JWT的使用场景
1)身份认证:用户登录后生成 JWT,之后每次请求时验证 JWT 以实现认证。
2)授权:通过 JWT 传递用户权限信息,确保用户只能访问被授权的资源。
3)信息传递:JWT 可以安全地传输一些加密的信息。
5. JWT 的安全性注意事项
签名算法:建议使用强大的签名算法(如 HS256 或 RS256),避免使用不安全的算法。
HTTPS:JWT 中可能包含敏感信息,传输时必须使用 HTTPS 来防止令牌被截获。
令牌过期:为 JWT 设置合理的过期时间(exp 声明),防止长期有效的令牌被滥用。
刷新令牌:使用短期有效的访问令牌和长期有效的刷新令牌(Refresh Token)机制,以便在访问令牌过期后请求新的令牌。
6.Java代码实现生成和验证JWT
6.1.添加Maven依赖
如果你使用 Maven 构建项目,首先在 pom.xml 中添加 JJWT 库的依赖:
| <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> </dependency> |
6.2.生成和验证 JWT 的 Java 代码
| package com.me.mengyu.auth.net.jwt; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.Claims; import io.jsonwebtoken.security.Keys; import javax.crypto.SecretKey; import java.util.Date; public class JwtExample { // 生成一个密钥,用于签名 private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 创建 JWT public static String createJwt(String subject) { // 设置 JWT 过期时间 long expirationTime = 1000 * 60 * 60; // 1 小时 return Jwts.builder() .setSubject(subject) // 设置主题(可以是用户ID等信息) .setIssuer("your-app") // 设置发行者 .setIssuedAt(new Date()) // 设置签发时间 .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 设置过期时间 .signWith(SECRET_KEY) // 使用密钥签名 .compact(); // 生成 JWT } // 验证 JWT 并提取信息 public static void validateJwt(String token) { try { // 解析 JWT Claims claims = Jwts.parserBuilder() .setSigningKey(SECRET_KEY) // 设置密钥 .build() .parseClaimsJws(token) // 验证令牌 .getBody(); // 输出从 JWT 中提取的信息 System.out.println("Subject: " + claims.getSubject()); System.out.println("Issuer: " + claims.getIssuer()); System.out.println("Expiration: " + claims.getExpiration()); } catch (Exception e) { System.out.println("Invalid JWT token: " + e.getMessage()); } } public static void main(String[] args) { // 创建 JWT String jwt = createJwt("1234567890"); // 这里的主题可以是用户的ID System.out.println("Generated JWT: " + jwt); // 验证 JWT validateJwt(jwt); } } |
代码说明:
1)createJwt 方法:生成一个带有签名的 JWT,包含用户身份信息(subject),签发者(issuer),签发时间和过期时间。使用 HS256 算法和一个密钥签名。
2) validateJwt 方法:验证 JWT 是否有效,并从中提取 claims 信息(如 subject,issuer,expiration)。如果令牌无效(例如过期或签名不匹配),会抛出异常。
运行结果示例:
| Generated JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaXNzIjoieW91ci1hcHAiLCJpYXQiOjE3MjcwMTcyNDYsImV4cCI6MTcyNzAyMDg0Nn0.tNylO-O5Jbazd0QzR85X8OB7p1mDy0IGtyl97Ro0FYQ Subject: 1234567890 Issuer: your-app Expiration: Mon Sep 23 00:00:46 CST 2024 |
说明:
生成的 JWT:格式为 header.payload.signature,其中 payload 包含 sub(用户ID)、iss(发行者)等信息。
验证:输出 Subject、Issuer 和 Expiration,表明 JWT 验证成功并解析出了信息。
6.3.注意事项
1)密钥管理:在生产环境中,应该安全地管理密钥,避免泄露。
2)过期时间:务必设置合理的过期时间,防止长时间有效的令牌带来安全风险。
3)异常处理:应当详细处理验证失败的情况,比如过期令牌、签名错误等。
相关文章:
JWT的基础与使用
JWT(JSON Web Token) 是一种用于在各方之间传输信息的紧凑、安全的方式,常用于身份验证和授权。它以令牌的形式将用户信息编码后传输,可以确保数据的完整性和安全性。 1.JWT的结构 JWT 是一个基于 JSON 的令牌,由三部…...
处理 VA02修改行项目计划行(SCHEDULE LINES )报错:不可能确定一个消耗帐户
用户修改销售订单行项目 计划行(SCHEDULE LINES) ,从 “CN”改为“CB”时候发生报错提示:不可能确定一个消耗帐户。 Not possible to determine a consumption account Message No. 06138 Diagnosis The system was not able to determine a consumpti…...
【AI基础】pytorch lightning 基础学习
传统pytorch工作流是首先定义模型框架,然后写训练和验证,测试循环代码。训练,验证,测试代码写起来比较繁琐。这里介绍使用pytorch lightning 部署模型,加速模型训练和验证,记录。 准备工作 1 安装pytorch…...
高通量测序技术--组蛋白甲基化修饰、DNA亲和纯化测序,教授(优青)团队指导:从实验设计、结果分析到SCI论文辅助
组蛋白甲基化修饰工具(H3K4me3 ChIP-seq)组蛋白甲基化类型也有很多种,包括赖氨酸甲基化位点H3K4、H3K9、H3K27、H3K36、H3K79和H4K20等。组蛋白H3第4位赖氨酸的甲基化修饰(H3K4)在进化上高度保守,是被研究最多的组蛋白修饰之一。 DNA亲和纯化测序 DNA亲…...
[极客大挑战 2019]RCE ME1
<?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($code); } else{highlight_file(__FILE__); }// ?>…...
计算机毕业设计 中医院问诊系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
FME辅助规划选址
1.需求:新建运动场馆 用地需求:至少1km*2km 找到符合要求的储备地块 2.已有资源:储备用地 现在城市地块储备比较充足,但都是不规则地块 找出可以建大型场馆的地块 3.问题分析 图斑内部可以放下1000*2000的矩形 4.解决思路…...
Unity中的GUIStyle错误:SerializedObject of SerializedProperty has been Disposed.
一运行就循环打印这个报错, 解决办法,每次改参数之后在HIerarchy中手动保存,就会停止循环打印,style中的字体也显示出来了, 或者 直接换个低版本的...
实战篇 | WSL迁移Linux系统到非系统盘(完整实操版)
1. 操作步骤 1.1 确认要导出的Linux系统是否存在(可跳过) # 终端命令 # 查看通过WSL安装的Linux系统列表 wsl -l1.2 导出Linux系统为tar包 # 终端命令 # 格式(过) wsl --export <Distribution Name> <File Name> #…...
增量式编码器实现原理
目录 概述 1 认识增量式编码器 1.1 概述 1.2 增量式编码器的特性 1.3 编码器的硬件 2 增量式编码器实现原理 2.1 编码器信号 2.2 正反转判断 概述 本文主要介绍增量式编码器实现原理,包括增量式编码器的特性,信号特性,以及如何使用编…...
数据集-目标检测系列-口罩检测数据集 mask>> DataBall
数据集-目标检测系列-口罩检测数据集 mask>> DataBall 数据集-目标检测系列-口罩检测数据集 mask 数据量:1W DataBall 助力快速掌握数据集的信息和使用方式,享有百种数据集,持续增加中。 数据项目地址: gitcode: https…...
工作安排 - 华为OD统一考试(E卷)
2024华为OD机试(C卷+D卷)最新题库【超值优惠】Java/Python/C++合集 题目描述 小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的耗时时长(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和。那么请你帮小明安排一下工作,保证小明在指定…...
STM32 GPIO - 笔记
1 STM32的GPIO是漏还是源 在 STM32 微控制器中,GPIO(通用输入/输出)引脚既可以配置为漏极开路输出(Open-Drain)模式,也可以配置为推挽输出(Push-Pull)模式。因此,GPIO 引脚既可以作为“漏”(吸电流,Open-Drain),也可以作为“源”(供电流,Push-Pull)来使用。 GP…...
三篇文章速通JavaSE到SpringBoot框架 (中) IO 进程线程 网络编程 XML MySQL JDBC相关概念与演示代码
文章目录 IOfile类的作用I/O的作用将上篇文章综合项目使用IO流升级所需知识点 进程 线程创建线程的三种方式 网络编程网络编程介绍IP地址端口号网络通信协议网络通信协议的分层演示代码 XMLXML的作用是什么?xml特点 注解什么是注解?注解的使用注解的重要…...
Linux下的基本指令/命令(二)
热键 Tab: 连点两次 对命令进补齐 或者 显式 以目前所需字母 开头的指令。 也可以进行路径补齐 或者 显示所写的文件所处路径上的所有文件。 如果什么也没写,直接按Tab会显示所有命令 Ctrl C: 一旦出现失控的状态,或者任何无法…...
CentOs-Stream-9 设置静态IP外网访问
CentOs-Stream-9 设置静态IP,实现外网访问。这里面有些需要注意的地方,比如IP网段跟我们的宿主机不一样,需要查看具体的网络适配器网段,这样可以快速实现网络互通;另外它的网络配置文件也是不一样的。网络适配器对应的…...
精密制造的革新:光谱共焦传感器与工业视觉相机的融合
在现代精密制造领域,对微小尺寸、高精度产品的检测需求日益迫切。光谱共焦传感器凭借其非接触、高精度测量特性脱颖而出,而工业视觉相机则以其高分辨率、实时成像能力著称。两者的融合,不仅解决了传统检测方式在微米级别测量上的局限…...
边缘计算与 Python Web 应用:从理论到实践
边缘计算与 Python Web 应用:从理论到实践 目录 🌐 边缘计算基础 1.1 边缘计算的概念与云计算的区别1.2 边缘计算在物联网(IoT)与实时应用中的作用 🖥️ Python 在边缘设备上的部署 2.1 在 Raspberry Pi、Jetson Nan…...
华为OD机试真题------分糖果
题目描述: 小明从糖果盒中随意抓一把糖果,每次小明会取出一半的糖果分给同学们。当糖果不能平均分配时,小明可以选择从糖果盒中(假设盒中糖果足够)取出一个糖果或放回一个糖果。小明最少需要多少次(取出、放…...
Kotlin:变量声明,null安全,条件语句,函数,类与对象
目录 一,变量声明 1.1 var和val 1.2 类型推断 1.3 Null安全 1.3.1 处理可为null性 二,条件语句 2.1条件语句与条件表达式 2.2 智能类型转换 三,函数 3.1 简化函数声明 3.2 匿名函数 3.3 高阶函数 四,类与对象 4.1 构…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
