JWT 令牌
目录
一、JWT
1、什么是JWT
2、JWT的组成
3、JJWT签发与验证token
1、创建token
2、解析token
3、设置过期时间
4、自定义claims
前言:
在现代Web应用和微服务架构中,用户身份验证和信息安全传输是核心问题。JSON Web Token(JWT)作为一种轻量级的认证机制,已成为开发者解决这些问题的重要工具。通过它,系统可以实现无状态认证,不需要在服务器端存储会话信息,既提高了性能,又增强了可扩展性。本文将介绍JWT的基本概念、组成部分以及它的token令牌的生成与校验。
一、JWT
1、什么是JWT
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境中作为紧凑的、独立的方式安全地传递信息。JWT通常用于用户身份验证和信息交换,尤其是在Web应用和微服务架构中。
2、JWT的组成
-
头部(Header):通常包含两部分信息,算法类型(如HMAC SHA256或RSA)以及令牌的类型(通常是JWT)。
头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象。
{"typ":"JWT","alg":"HS256"}
在头部指明了签名算法是HS256算法。 我们进行BASE64编码http://base64.xpcha.com/,编码后的字符串如下:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
-
负载(Payload):包含声明(Claims)。声明是关于实体(通常是用户)以及额外数据的信息。声明有三种类型:
- 注册声明:这些是JWT规范中推荐的标准声明,如
iss
(签发者)、exp
(过期时间)、sub
(主题)等。 - 公共声明:可以自由定义的声明,但需要避免冲突。
- 私有声明:是JWT中双方自行约定的声明,用于传递应用程序自定义信息。
- 注册声明:这些是JWT规范中推荐的标准声明,如
用白话说负载就是存放有效信息的地方。
定义一个payload:
{"sub":"1234567890","name":"John Doe","admin":true}
然后将其进行base64加密,得到Jwt的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
-
签名(Signature):为了确保JWT的安全性,使用头部和负载部分,再加上一个密钥,按照头部中指定的签名算法(如HMAC SHA256)生成签名。这个签名可以验证消息是否在传输过程中被篡改过。
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
header (base64后的)
payload (base64后的)
secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
将这三部分用.连接成一个完整的字符串,构成了最终的jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWT的主要优势是其自包含性,信息可以存储在令牌内部,服务器不需要保存会话信息,从而提高了可扩展性和性能。
3、JJWT签发与验证token
JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。
1、创建token
首先要在项目的pom文件中添加依赖,如下:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
接下来创建测试类,代码如下
JwtBuilder builder= Jwts.builder().setId("888") //设置唯一编号.setSubject("小白")//设置主题 可以是JSON数据.setIssuedAt(new Date())//设置签发日期.signWith(SignatureAlgorithm.HS256,"java");//设置签名 使用HS256算法,并设置SecretKey(字符串)
//构建 并返回一个字符串
System.out.println( builder.compact() );
运行打印结果:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDQxODF9.ThecMfgYjtoys3JX7dpx3hu6pUm0piZ0tXXreFU_u3Y
再次运行,会发现每次运行的结果是不一样的,因为我们的载荷中包含了时间。
2、解析token
我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息查询数据库返回相应的结果。
String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDQxODF9.ThecMfgYjtoys3JX7dpx3hu6pUm0piZ0tXXreFU_u3Y";
Claims claims = Jwts.parser().setSigningKey("java").parseClaimsJws(compactJwt).getBody();
System.out.println(claims);
运行打印效果:
{jti=888, sub=小白, iat=1557904181}
试着将token或签名秘钥篡改一下,会发现运行时就会报错,所以解析token也就是验证token。
3、设置过期时间
有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个过期时间。
创建token 并设置过期时间:
//当前时间
long currentTimeMillis = System.currentTimeMillis();
Date date = new Date(currentTimeMillis);
JwtBuilder builder= Jwts.builder().setId("888") //设置唯一编号.setSubject("小白")//设置主题 可以是JSON数据.setIssuedAt(new Date())//设置签发日期.setExpiration(date).signWith(SignatureAlgorithm.HS256,"java");//设置签名 使用HS256算法,并设置SecretKey(字符串)
//构建 并返回一个字符串
System.out.println( builder.compact() );
解释:
.setExpiration(date)//用于设置过期时间 ,参数为Date类型数据
运行,打印效果如下:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDUzMDgsImV4cCI6MTU1NzkwNTMwOH0.4q5AaTyBRf8SB9B3Tl-I53PrILGyicJC3fgR3gWbvUI
解析TOKEN:
String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDUzMDgsImV4cCI6MTU1NzkwNTMwOH0.4q5AaTyBRf8SB9B3Tl-I53PrILGyicJC3fgR3gWbvUI";
Claims claims = Jwts.parser().setSigningKey("java").parseClaimsJws(compactJwt).getBody();
System.out.println(claims);
打印结果:
当前时间超过过期时间,则会报错。
4、自定义claims
我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角色)可以定义自定义claims。
创建测试类,并设置测试方法:
创建token:
@Test
public void createJWT(){//当前时间long currentTimeMillis = System.currentTimeMillis();currentTimeMillis+=1000000L;Date date = new Date(currentTimeMillis);JwtBuilder builder= Jwts.builder().setId("888") //设置唯一编号.setSubject("小白")//设置主题 可以是JSON数据.setIssuedAt(new Date())//设置签发日期.setExpiration(date)//设置过期时间.claim("roles","admin")//设置角色.signWith(SignatureAlgorithm.HS256,"java");//设置签名 使用HS256算法,并设置SecretKey(字符串)//构建 并返回一个字符串System.out.println( builder.compact() );
}
运行打印效果:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDU4MDIsImV4cCI6MTU1NzkwNjgwMiwicm9sZXMiOiJhZG1pbiJ9.AS5Y2fNCwUzQQxXh_QQWMpaB75YqfuK-2P7VZiCXEJI
解析TOKEN:
//解析
@Test
public void parseJWT(){String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDU4MDIsImV4cCI6MTU1NzkwNjgwMiwicm9sZXMiOiJhZG1pbiJ9.AS5Y2fNCwUzQQxXh_QQWMpaB75YqfuK-2P7VZiCXEJI";Claims claims = Jwts.parser().setSigningKey("java").parseClaimsJws(compactJwt).getBody();System.out.println(claims);
}
运行效果:
相关文章:

JWT 令牌
目录 一、JWT 1、什么是JWT 2、JWT的组成 3、JJWT签发与验证token 1、创建token 2、解析token 3、设置过期时间 4、自定义claims 前言: 在现代Web应用和微服务架构中,用户身份验证和信息安全传输是核心问题。JSON Web Token(J…...

Python基于Flask的豆瓣Top250电影数据可视化分析与评分预测系统(附源码,技术说明)
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
JavaScript数组-遍历数组
在JavaScript中,数组是一种非常常用的数据结构,用于存储一系列有序的数据项。无论是处理简单的列表还是复杂的数据集合,遍历数组都是我们经常需要执行的操作之一。本文将详细介绍几种常见的遍历数组的方法,并讨论它们各自的优缺点…...

基于Flask的第七次人口普查数据分析系统的设计与实现
【Flask】基于Flask的第七次人口普查数据分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 基于Flask的人口普查可视化分析系统 二、项目界面展示 登录/注册 首页/详情 …...

解决DeepSeek服务器繁忙的有效方法
全球42%的企业遭遇过AI工具服务器过载导致内容生产中断(数据来源:Gartner 2025)。当竞品在凌晨3点自动发布「智能家居安装指南」时,你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…...

分词器(Tokenizer) | 有了分词器,为什么还需要嵌入模型
文章目录 什么是tokenizer有了分词器,为什么还需要嵌入模型分词器为什么在transformers 里Hugging Face的Tokenizer大模型不同tokenizer训练效果对比分词器库选择当前顶尖大模型所采用的 Tokenizer 方法与词典大小 参考 什么是tokenizer Tokenizers huggingface官方…...

VisionTransformer(ViT)与CNN卷积神经网络的对比
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
计算机视觉+Numpy和OpenCV入门
Day 1:Python基础Numpy和OpenCV入门 Python基础 变量与数据类型、函数与类的定义、列表与字典操作文件读写操作(读写图像和数据文件) 练习任务:写一个Python脚本,读取一个图像并保存灰度图像。 import cv2 img cv2.im…...
Vue 3 工程化打包工具:从理论到实践 (下篇)
引言 在前端开发中,打包工具是工程化的重要组成部分。Vue 3 作为当前流行的前端框架,其工程化离不开高效的打包工具。打包工具不仅能够将代码、样式、图片等资源进行优化和压缩,还能通过模块化、代码分割等功能提升应用的性能。本文将深入探…...

java经验快速学习python!
title: java经验快速学习python! date: 2025-02-19 01:52:05 tags: python学习路线 java经验快速学习python! 本篇文档会一直更新!!!变量、分支结构、循环结构、数据结构【列表、元组、集合字典】python常用内置函数元…...

爬虫破解网页禁止F12
右击页面显示如下 先点击f12再输入网址,回车后没有加载任何数据 目前的一种解决方法: 先 AltD ,再 CtrlShifti...

从零开始构建一个语言模型中vocab_size(词汇表大小)的设定规则
从零开始构建一个语言模型就要设计一个模型框架,其中要配置很多参数。在自然语言处理任务中,vocab_size(词汇表大小) 的设定是模型设计的关键参数之一,它直接影响模型的输入输出结构、计算效率和内存消耗。 本文是在我前文的基础上讲解的:从零开始构建一个小型字符级语言…...

Jenkins插件管理切换国内源地址
安装Jenkins 插件时,由于访问不了国外的插件地址,会导致基本插件都安装失败。 不用着急,等全部安装失败后,进入系统,修改插件源地址,重启后在安装所需插件。 替换国内插件更新地址 选择:系统…...
Q - learning 算法是什么
Q - learning 算法是什么 Q - learning 算法是一种经典的无模型强化学习算法,由克里斯沃特金斯(Chris Watkins)在 1989 年提出。它被广泛应用于解决各种决策问题,尤其适用于智能体在环境中通过与环境交互来学习最优策略的场景。下面从基本概念、核心公式、算法流程和特点几…...
nasm - console 32bits
文章目录 nasm - console 32bits概述笔记my_build.batnasm_main.asm用VS2019写个程序,按照win32方式编译,比较一下。备注END nasm - console 32bits 概述 看到一个nasm的例子(用nasm实现一个32bits控制台的程序架子) 学习一下 笔记 my_build.bat ec…...

11.编写前端内容|vscode链接Linux|html|css|js(C++)
vscode链接服务器 安装VScode插件 Chinese (Simplified) (简体中⽂) Language Pack for Visual Studio CodeOpen in BrowserRemote SSH 在命令行输入 remote-ssh接着输入 打开配置文件,已经配置好主机 点击远程资源管理器可以找到 右键链接 输入密码 …...

【deepseek-r1模型】linux部署deepseek
1、快速安装 Ollama 下载:Download Ollama on macOS Ollama 官方主页:https://ollama.com Ollama 官方 GitHub 源代码仓库:https://github.com/ollama/ollama/ 官网提供了一条命令行快速安装的方法。 (1)下载Olla…...
【Github每日推荐】-- 2024 年项目汇总
1、AI 技术 项目简述OmniParser一款基于纯视觉的 GUI 智能体,能够准确识别界面上可交互图标以及理解截图中各元素语义,实现自动化界面交互场景,如自动化测试、自动化操作等。ChatTTS一款专门为对话场景设计的语音生成模型,主要用…...
C++中的.*运算符
看运算符重载的时候,看到这一句 .* :: sizeof ?: . 注意以上5个运算符不能重载。 :: sizeof ?: . 这四个好理解,毕竟都学过,但.*是什么? 于是自己整理了一下 .* 是一种 C 中的运算符,称为指针到成…...

深度学习笔记——LSTM
大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的LSTM知识点。 文章目录 LSTM(Long Short-Term Memory)LSTM 的核心部件LSTM 的公式和工作原理(1) 遗忘门&a…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...

Ray框架:分布式AI训练与调参实践
Ray框架:分布式AI训练与调参实践 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 Ray框架:分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...

Linux【5】-----编译和烧写Linux系统镜像(RK3568)
参考:讯为 1、文件系统 不同的文件系统组成了:debian、ubuntu、buildroot、qt等系统 每个文件系统的uboot和kernel是一样的 2、源码目录介绍 目录 3、正式编译 编译脚本build.sh 帮助内容如下: Available options: uboot …...
Java求职者面试:微服务技术与源码原理深度解析
Java求职者面试:微服务技术与源码原理深度解析 第一轮:基础概念问题 1. 请解释什么是微服务架构,并说明其优势和挑战。 微服务架构是一种将单体应用拆分为多个小型、独立的服务的软件开发方法。每个服务都运行在自己的进程中,并…...