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 构…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...