当前位置: 首页 > news >正文

jwt的了解和使用以及大致代码分析

jwt简介

以下介绍来自官网(https://jwt.io/)
SON Web 令牌 (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间以 JSON 对象的形式安全地传输信息。此信息可以验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名**(来自官网)**。

尽管 JWT 可以加密以提供各方之间的保密性,但我们将专注于签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌则向其他方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是签名的一方**(来自官网)**。

使用场景

  • 授权:这是使用 JWT 的最常见方案。用户登录后,每个后续请求都将包含 JWT,允许用户访问使用该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小,并且能够跨不同域轻松使用**(来自官网)**。

  • 信息交换:JSON Web 令牌是在各方之间安全传输信息的好方法。由于 JWT 可以签名(例如,使用公钥/私钥对),因此您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改**(来自官网)**)。

jwt的组成结构

  • Header
  • Payload
  • Signature
    因此,JWT 通常如下所示。
xxxxx.yyyyy.zzzzz

Header

通常由两部分组成:令牌的类型(即 JWT)和正在使用的签名算法,例如 HMAC SHA256 或 RSA。
例如:

{"alg": "HS256","typ": "JWT"
}

然后,此JSON被Base64Url编码以形成JWT的第一部

Payload(有效载荷)

令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的语句。
有三种类型的声明:已注册、公共和私人声明。
已注册声明:这些是一组预定义的声明,这些声明不是必需的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是:iss(发行人),exp(到期时间),sub(主题),aud(受众)等。

请注意,声明名称只有三个字符长,因为 JWT 应该是紧凑的。

公共声明:这些可以由使用 JWT 的人随意定义。但为了避免冲突,它们应该在 IANA JSON Web 令牌注册表中定义,或者定义为包含抗冲突命名空间的 URI。

专用声明:这些是创建的自定义声明,用于在同意使用它们的各方之间共享信息,既不是注册声明也不是公共声明。

示例有效负载可以是:

{"sub": "1234567890","name": "John Doe","admin": true
}

sub是预定义的声明,name,admin则是自己随便添加的一些定义
然后对有效负载进行 Base64Url 编码以形成 JSON Web 令牌的第二部分。

请注意,对于签名令牌,此信息虽然受到篡改保护,但任何人都可以读取。不要将机密信息放在 JWT 的有效负载或标头元素中,除非它已加密。

签名

要创建签名部分,您必须获取编码的标头、编码的有效负载、机密、标头中指定的算法并对其进行签名。

例如,如果要使用 HMAC SHA256 算法,将按以下方式创建签名:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

签名用于验证消息在此过程中未被更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发件人是否是它所说的人。

把所有东西放在一起
输出是三个由点分隔的 Base64-URL 字符串,可以在 HTML 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(如 SAML)相比更加紧凑。

使用java-jwt来生成和解析token

导入maven依赖

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version></dependency>

这附上一段我之前写的代码

    public String getToken(Users user) {String token="";// 2*24*3600 * 1000token= JWT.create().withExpiresAt(new Date(System.currentTimeMillis() + (2*24*3600*1000))).withAudience(user.getEmployeeId())// 将 login_user 保存到 token 里面.sign(Algorithm.HMAC256(DigestUtils.md5Hex(user.getEmployeePassword()+ Constants.MD5PRIVATEKEY)));// 以 password 作为 token 的密钥return token;}

这是上面引入的依赖提供的方法
首先是 JWT.create(),create方法去调用了JWTCreator的init方法

public static JWTCreator.Builder create() {return JWTCreator.init();}

然后init方法又new了一个自己的内部类,内部类给头部(headerClaims)和载荷(payloadClaims)声明了引用地址

    /*** Initialize a JWTCreator instance.** @return a JWTCreator.Builder instance to configure.*/static JWTCreator.Builder init() {return new Builder();}/*** The Builder class holds the Claims that defines the JWT to be created.*/public static class Builder {private final Map<String, Object> payloadClaims;private Map<String, Object> headerClaims;Builder() {this.payloadClaims = new HashMap<>();this.headerClaims = new HashMap<>();}

紧接着withExpiresAt()和withAudience()实际上就是给载荷里预定义的声明赋值,withExpiresAt()就是给exp赋值,withAudience()就是给aud赋值

     /*** Add a specific Audience ("aud") claim to the Payload.** @param audience the Audience value.* @return this same Builder instance.*/public Builder withAudience(String... audience) {addClaim(PublicClaims.AUDIENCE, audience);return this;}/*** Add a specific Expires At ("exp") claim to the Payload.** @param expiresAt the Expires At value.* @return this same Builder instance.*/public Builder withExpiresAt(Date expiresAt) {addClaim(PublicClaims.EXPIRES_AT, expiresAt);return this;}

它们都调用了addClaim方法,可以看到就是在载荷的那个map中添加key和value

 private void addClaim(String name, Object value) {if (value == null) {payloadClaims.remove(name);return;}payloadClaims.put(name, value);}

前面说过也可以自定义声明添加到载荷这部分,这里也提供了多个方法,这里展示两个

   /*** Add a custom Claim value.** @param name  the Claim's name.* @param value the Claim's value.* @return this same Builder instance.* @throws IllegalArgumentException if the name is null.*/public Builder withClaim(String name, Boolean value) throws IllegalArgumentException {assertNonNull(name);addClaim(name, value);return this;}/*** Add a custom Claim value.** @param name  the Claim's name.* @param value the Claim's value.* @return this same Builder instance.* @throws IllegalArgumentException if the name is null.*/public Builder withClaim(String name, Integer value) throws IllegalArgumentException {assertNonNull(name);addClaim(name, value);return this;}

然后是sign()方法,这里这里传入了一个我们指明秘钥的算法,headerClaims.put方法给头部添加了令牌的类型(即 JWT)和正在使用的签名算法

/*** Creates a new JWT and signs is with the given algorithm** @param algorithm used to sign the JWT* @return a new JWT token* @throws IllegalArgumentException if the provided algorithm is null.* @throws JWTCreationException     if the claims could not be converted to a valid JSON or there was a problem with the signing key.*/public String sign(Algorithm algorithm) throws IllegalArgumentException, JWTCreationException {if (algorithm == null) {throw new IllegalArgumentException("The Algorithm cannot be null.");}headerClaims.put(PublicClaims.ALGORITHM, algorithm.getName());headerClaims.put(PublicClaims.TYPE, "JWT");String signingKeyId = algorithm.getSigningKeyId();if (signingKeyId != null) {withKeyId(signingKeyId);}return new JWTCreator(algorithm, headerClaims, payloadClaims).sign();}

然后new 了一个JWTCreator对象

 private JWTCreator(Algorithm algorithm, Map<String, Object> headerClaims, Map<String, Object> payloadClaims) throws JWTCreationException {this.algorithm = algorithm;try {ObjectMapper mapper = new ObjectMapper();SimpleModule module = new SimpleModule();module.addSerializer(ClaimsHolder.class, new PayloadSerializer());mapper.registerModule(module);mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);headerJson = mapper.writeValueAsString(headerClaims);payloadJson = mapper.writeValueAsString(new ClaimsHolder(payloadClaims));} catch (JsonProcessingException e) {throw new JWTCreationException("Some of the Claims couldn't be converted to a valid JSON format.", e);}}

这里可以看到这两句代码,把头部这个map和载荷这个map都转换成了json串

  headerJson = mapper.writeValueAsString(headerClaims);payloadJson = mapper.writeValueAsString(new ClaimsHolder(payloadClaims));

然后返回,在new一个JWTCreator对象后又调用了这个对象的sign()方法

 private String sign() throws SignatureGenerationException {String header = Base64.encodeBase64URLSafeString(headerJson.getBytes(StandardCharsets.UTF_8));String payload = Base64.encodeBase64URLSafeString(payloadJson.getBytes(StandardCharsets.UTF_8));String content = String.format("%s.%s", header, payload);byte[] signatureBytes = algorithm.sign(content.getBytes(StandardCharsets.UTF_8));String signature = Base64.encodeBase64URLSafeString((signatureBytes));return String.format("%s.%s", content, signature);}

可以看到首先对header也就是头部做了base64编码,然后对载荷 payload也做了base64编码

String header = Base64.encodeBase64URLSafeString(headerJson.getBytes(StandardCharsets.UTF_8));
String payload = Base64.encodeBase64URLSafeString(payloadJson.getBytes(StandardCharsets.UTF_8));

然后使用小数点连接

String content = String.format("%s.%s", header, payload);

然后使用算法对连接后的头部和载荷进行签名,最后形成签名

byte[] signatureBytes = algorithm.sign(content.getBytes(StandardCharsets.UTF_8));

然后用base64对签名进行编码,再把编码后的签名和前面的头部,载荷连接起来

String signature = Base64.encodeBase64URLSafeString((signatureBytes));return String.format("%s.%s", content, signature);

相关文章:

jwt的了解和使用以及大致代码分析

jwt简介 以下介绍来自官网&#xff08;https://jwt.io/&#xff09; SON Web 令牌 &#xff08;JWT&#xff09; 是一种开放标准 &#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且独立的方式&#xff0c;用于在各方之间以 JSON 对象的形式安全地传输信息。此信…...

uniapp中videojs、renderjs的使用

在uniapp中使用了某些前端库或iframe&#xff0c;需要操作这些库中的dom的时候&#xff0c; 而uni上又没有document等基础对象。也就无法操作这些dom去实现一些交互逻辑&#xff0c;那么&#xff0c;涉及到这些的前端类库就无法使用&#xff0c;例如html2、canvas、image、vide…...

AIGC AI绘画 Midjourney 参数大全详细列表

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作, Power BI 商业智能 68集, 数据库Mysql8.0 54集 数据库Oracle21C 142集, Office 2021实战, Python 数据分析, ETL Informatica 案例实战 Excel 2021实操,函数大全,图表大全,大屏可视化制作 加技巧500集 数据分析可视化T…...

安装hadoop,并配置hue

0、说明 对于大数据学习的初始阶段&#xff0c;我也曾尝试搭建相应的集群环境。通过搭建环境了解组件的一些功能、配置、原理。 在实际学习过程中&#xff0c;我更多的还是使用docker来快速搭建环境。 这里记录一下我搭建hadoop的过程。 1、下载hadoop 下载地址&#xff1a;…...

23种经典设计模式:单例模式篇(C++)

前言&#xff1a; 博主将从此篇单例模式开始逐一分享23种经典设计模式&#xff0c;并结合C为大家展示实际应用。内容将持续更新&#xff0c;希望大家持续关注与支持。 什么是单例模式&#xff1f; 单例模式是设计模式的一种&#xff08;属于创建型模式 (Creational Pa…...

ros中对move_base的调用

move_base包中自带costmap2d, global planner 等功能 也可以直接调用其中make_plan进行路径规划 #include "geometry_msgs/PoseStamped.h" #includde "nav_msgs/GetPlan.h"void fillPathRequest(nav_msgs::GetPlan::Request &request, float start_x…...

Git从本地库撤销已经添加的文件或目录

场景 在提交时, 误将一个目录添加到了暂存区, 而且commit 了本地库,同批次commit 的还有其他需要提交的文件。 commit 之后发现这个目录下所有的文件都不需要提交, 现在需要撤销这个提交, 使这个目录不被push到远端库。 这里以远端服务器github 为例,在Git GUI下看到的…...

百度SEO优化的特点(方式及排名诀窍详解)

百度SEO优化的特点介绍&#xff1a; 百度SEO优化是指对网站进行优化&#xff0c;使其在百度搜索引擎中获得更好的排名&#xff0c;进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新&#xff0c;所以长期稳定的…...

Gin 文件上传操作(单/多文件操作)

参考地址: 单文件 | Gin Web Framework (gin-gonic.com)https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file/ 单文件 官方案例: func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)router.MaxMultipartMem…...

分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测

分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-LSTM开普勒算法优化…...

Qt应用开发(基础篇)——列表视图 QListView

一、前言 QListView类继承于QAbstractItemView类&#xff0c;提供了一个列表或者图标视图的模型。 视图基类 QAbstractItemView QListView效果相当于Windows文件夹右键->查看->图标和列表&#xff0c;使用setViewMode()设置视图模式&#xff0c;并且提供setIconSize()函数…...

vue-6

一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话&#xff0c;需要给当前跳转的导航加样式&#xff0c;同时要移除上一个a标签的样式&#xff0c;太麻烦&#xff01;&#xff01;&#xff01; 2.解决方案 vue-router 提供了一个全局组件 router…...

温度在线检测技术在电力电缆线路的应用

在电力电缆的日常运行检测中&#xff0c;针对电缆温度的状况&#xff0c;所采用的电力温度在线检测技术也得到了大范围的普及。电网系统中&#xff0c;其单位时间内可输送的电力能源受到其温度的变化影响。因此&#xff0c;采用更有效的方式实时检测电缆系统运行温度&#xff0…...

2023年中国自动化微生物样本处理系统竞争现状及行业市场规模分析[图]

微生物检测能够对感染性疾病的病原体或者代谢物进行检测分析&#xff0c;是IVD的细分领域之一。2022年中国体外诊断市场规模1424亿元。 2015-2022年中国体外诊断市场规模 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; 微生物检测由于样本类型多样&#xf…...

硬链接和软连接的区别

软链接&#xff08;也称为软连接或符号链接&#xff09;是一种特殊的文件&#xff0c;其内容是另一个文件的路径。当你使用软链接时&#xff0c;实际上是在操作另一个文件。软链接的优点是它可以跨文件系统使用&#xff0c;因此可以跨分区或磁盘链接文件。此外&#xff0c;软链…...

保护隐私与增强网络安全之网络代理技术

目录 前言 一、网络代理技术原理 二、网络代理技术类型 1. HTTP代理 2. SOCKS代理 3. DNS代理 4. 加密代理 5. 反向代理 三、网络代理技术应用 1. 加速网络访问速度 2. 绕过网络限制 3. 保护个人隐私 4. 节省带宽 5. 改善网络安全 四、网络代理技术优缺点 网络…...

【每日一题】CF1680C. Binary String | 双指针 | 简单

题目内容 原题链接 给定一个长度为 n n n 的 01 01 01 字符串&#xff0c;对于一个子串 s u b sub sub &#xff0c;子串内部的 0 0 0 的数量为 x x x &#xff0c;子串以外的 1 1 1 的数量为 y y y &#xff0c;子串的代价为 m a x ( x , y ) max(x, y) max(x,y) &…...

10.selenium进阶

文章目录 1、嵌套网页1、1 什么是嵌套页面1、2 selenium获取嵌套页面的数据 2、执行JavaScript代码3、鼠标动作链4、selenium键盘事件5、其他方法5、1 选择下拉框5、2 弹窗的处理 6、selenium设置无头模式7、selenium应对检测小结 1、嵌套网页 ​ 在前端开发中如果有这么一个需…...

【安全】 Java 过滤器 解决存储型xss攻击问题

文章目录 XSS简介什么是XSS?分类反射型存储型 XSS(cross site script)跨站脚本攻击攻击场景解决方案 XSS简介 跨站脚本( cross site script )为了避免与样式css(Cascading Style Sheets层叠样式表)混淆&#xff0c;所以简称为XSS。 XSS是一种经常出现在web应用中的计算机安全…...

一、Excel VBA 是个啥?

Excel VBA 从入门到出门一、Excel VBA 是个啥&#xff1f;二、Excel VBA 简单使用 &#x1f44b;Excel VBA 是个啥&#xff1f; ⚽️1. Excel 中的 VBA 是什么&#xff1f;⚽️2. 为什么 VBA 很重要&#xff1f;⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…...

OpenClaw压力测试:百川2-13B-4bits模型连续处理100个文件的稳定性

OpenClaw压力测试&#xff1a;百川2-13B-4bits模型连续处理100个文件的稳定性 1. 测试背景与动机 上周在整理项目文档时&#xff0c;我遇到了一个典型问题&#xff1a;需要批量重命名103个Markdown文件&#xff0c;并从中提取关键字段生成目录索引。手动操作不仅耗时&#xf…...

从Demo到生产级:免费开源Agentic RAG实战课程,手把手教你构建智能系统!

Production Agentic RAG Course是一个免费开源课程&#xff0c;旨在帮助开发者从零构建生产级Agentic RAG系统。课程分为5个模块&#xff0c;共17节课&#xff0c;涵盖架构设计、工具集成、性能优化和生产部署等关键内容。Agentic RAG通过引入Agent能力&#xff0c;实现主动规划…...

使用 Aspen Plus 模拟天然气的自热转化

使用aspen plus模拟天然气的自热转化自热重整工艺消耗蒸汽和氧气&#xff0c;将天然气转化为合成气。 事实上&#xff0c;自热转化工艺是放热的部分氧化&#xff08;POX&#xff09;工艺和内热的蒸汽甲烷转化&#xff08;SMR&#xff09;工艺的结合&#xff0c;从热力学角度中和…...

ArcGIS Pro 3.0 气象数据处理实战:如何从365天的nc文件中提取单日降水数据

ArcGIS Pro 3.0 气象数据处理实战&#xff1a;从365天nc文件中精准提取单日降水数据 气象数据作为地理信息科学中的重要组成部分&#xff0c;其处理效率直接影响研究进度和成果质量。在众多气象数据格式中&#xff0c;NetCDF&#xff08;.nc&#xff09;因其结构化存储和多维数…...

C语言入门:了解历史与适用人群

要是您身为一名刚开始接触学习事物的人&#xff0c;再者您尚未弄明白何种属于编程语言&#xff0c;那就去瞧瞧这个了&#xff1a;什么是编程语言。 若您先前未曾接触过任何一种编程语言&#xff0c;或者您并不明白为何要是学习C语言来着&#xff0c;请看&#xff1a;为什么C语言…...

【国家级智慧农场落地案例】:Python图像算法如何将番茄裂果识别准确率提升至98.7%?

第一章&#xff1a;国家级智慧农场落地背景与番茄裂果识别挑战近年来&#xff0c;国家《“十四五”推进农业农村现代化规划》明确提出加快数字技术与农业生产深度融合&#xff0c;推动建设一批国家级智慧农场示范项目。在华北、华东等核心蔬菜产区&#xff0c;规模化番茄种植基…...

终极GitHub加速解决方案:让你的代码下载速度提升100倍

终极GitHub加速解决方案&#xff1a;让你的代码下载速度提升100倍 【免费下载链接】Fast-GitHub 国内Github下载很慢&#xff0c;用上了这个插件后&#xff0c;下载速度嗖嗖嗖的~&#xff01; 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否曾经因为G…...

3步搞定专业电路图绘制:Draw.io ECE插件让电子工程设计变得简单高效

3步搞定专业电路图绘制&#xff1a;Draw.io ECE插件让电子工程设计变得简单高效 【免费下载链接】Draw-io-ECE Custom-made draw.io-shapes - in the form of an importable library - for drawing circuits and conceptual drawings in draw.io. 项目地址: https://gitcode.…...

Jira替代工具如何选?2026年推荐十款适合小团队且容易上手项目管理平台

在数字化转型浪潮席卷全球的背景下&#xff0c;企业尤其是科技驱动型组织正加速将敏捷与精益理念融入核心运营流程。根据Gartner发布的报告&#xff0c;到2025年&#xff0c;超过80%的软件项目将采用敏捷或混合开发模式&#xff0c;这使得能够支撑高效协作与透明化管理的项目管…...

Java if 分支

一、什么是Java if条件语句&#xff1f;if条件语句是一种分支控制语句&#xff0c;核心逻辑是&#xff1a;先判断一个条件表达式的真假&#xff0c;若为true则执行一段代码&#xff0c;若为false则不执行&#xff08;或执行其他代码&#xff09;。二、Java if语句的4种核心语法…...