JWT介绍和使用

JWT介绍和使用

JWT介绍

JWT(JSON Web Token)是一个开放的标准(RFC 7519),JWT定义了一种简介的、自包含的协议格式。可以用于在通信的双方传递json对象,传递的信息可以被信任,因为信息是被数字签名的。JWT可以使用HMAC算法或者使用RSA/ECDSA算法的公钥/私钥对签名。

JWT格式

JWT包含三部分内容,Header、Plyload和Signature。

  • Header

    • 包括令牌的类型以及使用的哈希算法;使用base64url编码后就是JWT的第一部分内容
  • Payload

    • Payload的内容是一个json对象,它是存放有效信息的地方,可以存放jwt提供的现成字段,比如:iss(签发者),exp(过期时间戳信) ,sub(面向的用户)等;同时也可以自定义字段存放数据,但是不建议存放敏感数据,因为此部分可以解码还原原始内容;使用base64url编码后就是JWT的第二部分内容
  • Signature

    • Signature是签名,用于防止jwt内容被篡改,这个部分使用base64url将前两部分进行编码,编码后使用“.” 连接组成字符串,最后使用header中声明的签名算法进行签名。

假设现在一个JWT的Header和Payload部分内容如下
Header:

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

payload

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

那么Signature的的内容如下所示,“yguyhdqwodqwddqw1”是秘钥

HMACSHA384(base64UrlEncode(header) + "." +base64UrlEncode(payload),yguyhdqwodqwddqw1
)

最后生成的JWT如下:

eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.f7IalcwE38sVPor1FBUwAwso6exiwF80y0nM6bLkAvooNFGjCoJXRL0DMpaQB42C

payload和claims介绍

payload和claims的概念在JJWT开源库中使用了,所以这里简单介绍一下。

前面已经讲过了payload是一个JSON对象,包含了实际传输的数据。而Payload的主要目的是携带与特定用户或请求相关的信息,这些信息就被称为“claims”。

Claims(声明)是Payload中包含的具体键值对数据项,它们用来表述特定的声明或声明集,这些声明描述了与JWT相关的事实。根据其用途和规范要求,claims可以分为以下几类:

  • Reserved Claims(保留声明): 这些是JWT标准中预定义的、具有特殊含义的claims。虽然它们是可选的,但如果使用,应遵循标准规定的名称和格式。常见的保留claims包括:
    • iss(issuer):签发者。
    • sub(subject):主题,标识JWT所代表的个体。
    • aud(audience):接收方,标识预期的JWT接收者。
    • exp(expiration time):过期时间,定义了JWT的有效期截止时间。
    • nbf(not before):生效时间,在此时间之前JWT不应被接受处理。
    • iat(issued at):签发时间,表明JWT的创建时间。
    • jti(JWT ID):唯一标识符,用于防止JWT重放攻击。
  • Public Claims(公共声明)
    • 这些claims没有在JWT标准中明确规定,但可以通过IANA JSON Web Token Registry进行注册,以确保其名称在全球范围内是唯一的,避免不同系统间的冲突。公共claims通常用于满足特定的应用程序或行业需求。
  • Private Claims(私有声明)
    • 开发者可以自由定义的claims,用于承载应用程序所需的任何额外信息。私有claims无需注册,其名称由开发者自行决定,如示例中提到的user_id和user_name。这些声明对JWT的使用者具有特定意义,但对JWT标准本身来说是无特殊含义的。

JWT使用

jjwt是Java Json Web Tokens的缩写,它所示一个用于在Java中实现JWT的开源库。

jjwt依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version></dependency><!-- javax.xml.bind.DatatypeConverter 类已被弃用并从 Java SE 9 中移除--><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

这是自己写的JJWT工具类

public class JJWTUtils {private static final Logger logger = LoggerFactory.getLogger(JJWTUtils.class);private static final String SECRET = "mpd';dqw823djq3d902";/*** 生成token*/public static String getToken(Map<String, Object> map) {//设置内容JwtBuilder jwtBuilder = Jwts.builder().setClaims(map);Calendar instance = Calendar.getInstance();instance.add(Calendar.SECOND, 100);//设置过期时间, 100s后过期jwtBuilder.setExpiration(instance.getTime());String token = jwtBuilder.signWith(SignatureAlgorithm.HS256, SECRET.getBytes()).compact();return token;}/*** 校验token* @param token  jwt字符串* @return*/public static boolean verifyToken(String token) {String[] tokenSplit = token.split(".");String header = tokenSplit[0];String payload = tokenSplit[1];String signature = tokenSplit[2];String headerJson = new String(Base64.getDecoder().decode(header));String payloadJson = new String(Base64.getDecoder().decode(payload));byte[] keyBytes = SECRET.getBytes(StandardCharsets.UTF_8);Key signingKey = Keys.hmacShaKeyFor(keyBytes);// 验证JWT签名,如果JWT签名无效,这里会抛出SignatureException异常boolean result = true;try {Jwts.parser().setSigningKey(signingKey).parse(token);} catch (Exception e) {result = false;}return result;}/*** 获取token中的携带的信息*/public static Map<String, Object> getPayload(String token) {//claims是一个Map,存放了通过JwtBuilder设置进去的内容Claims claims = Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(token).getBody();return claims;}public static void main(String[] args) {HashMap<String, Object> payload = new HashMap<>();payload.put("name", "张三");payload.put("id", "1");String token = JJWTUtils.getToken(payload);logger.info("token: " + token);Map<String, Object> payload1 = JJWTUtils.getPayload(token);logger.info("payload1: " + payload1);}}

jjwt使用的坑

问题1
java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) … 6 more

解决方法
这个错是由于在Java8以后,javax.xml.bind.DatatypeConverter 类已被弃用并从 Java SE 9 中移除而导致的,所以加入缺少的依赖即可

        <dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

问题2
ava.lang.IllegalStateException: Both ‘payload’ and ‘claims’ cannot both be specified. Choose either one. at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:262) at com.example.sso.utils.JJWTUtils.getToken(JJWTUtils.java:38) at com.example.sso.utils.JJWTUtils.main(JJWTUtils.java:58)

解决方法

不能同时设置payload和claims。

参考

  1. Introduction to JSON Web Tokens

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决python3.10以上pyqt6-tools无法安装问题

情景描述 原本3.9版本python用的好好地&#xff0c;最新的一个自动化库要求必须要3.10以上才能使用。 火急火燎更新3.12版本python&#xff0c;结果安装qt-tools丫的安装不了了。 问题出现原因 python的pyqt-tools他不支持3.10以上的python版本下载。 如果想用pip下载得py…

【后端】Thymeleaf模板引擎学习笔记

文章目录 1. java体系模板引擎介绍2. 使用2.1 初步使用2.2. 引用静态资源模板2.3 引用静态资源模板(配置资源路径和后缀)2.4 整合springboot 视频地址 1. java体系模板引擎介绍 FreeMarkerThymeleafVelocity 2. 使用 2.1 初步使用 引入依赖 <dependency><groupId>…

C++学习随笔(11)——vector

本章我们来学习一下vector&#xff01; 目录 1.vector的介绍及使用 1.1 vector的介绍 1.2 vector的使用 1.2.1 vector的定义 1.2.2 vector iterator 的使用 1.2.3 vector 空间增长问题 1.2.4 vector 增删查改 1.2.5 vector 迭代器失效问题。 1.vector的介绍及使用 1…

selenium 自动化测试课上实操指南2——乐视tv搜索

如果完成了实操1的同学&#xff0c;环境搭建已经ok&#xff0c;环境还没有好的同学请参考 实操1_百度搜索 为了大家顺利&#xff0c;我们还想按照实操1那样&#xff0c;先导入一个基本项目。在次基础上进行代码编写、 我们一起写写看。 1.打开乐视视频网页并最大化 如下图所…

三款数据可视化工具深度解析:Tableau、ECharts与山海鲸可视化

在数字化时代&#xff0c;数据可视化工具成为了企业和个人进行数据分析和决策的重要助手。市面上众多数据可视化工具各具特色&#xff0c;本文将为您介绍三款热门的数据可视化工具&#xff0c;帮助您更好地理解和利用数据。 首先&#xff0c;让我们来认识Tableau。Tableau是一款…

matlab学习006-使用matlab绘出系统的冲激响应和阶跃响应波形并求其冲激响应的数值解

目录 题目 1&#xff0c;绘出系统的冲激响应和阶跃响应波形 1&#xff09;基础 2&#xff09;效果 3&#xff09;代码 2&#xff0c;求出t0.5s,1s,1.5s,2s时系统冲激响应的数值解。 1&#xff09;基础 2&#xff09;效果 ​☀ 3&#xff09;代码 题目 已知描述某连续系…

react之渲染与props

第一章描述用户界面 将Props 传递给组件 React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件&#xff0c;从而将一些信息传递给它。Props 可能会让你想起 HTML 属性&#xff0c;但你可以通过它们传递任何 JavaScript 值&#xff0c;包括对象、数组和…

《苍穹外卖》Day07部分知识点记录

一、菜品缓存 减少查询数据库的次数&#xff0c;优化性能 客户端&#xff1a; package com.sky.controller.user;import com.sky.constant.StatusConstant; import com.sky.entity.Dish; import com.sky.result.Result; import com.sky.service.DishService; import com.sky…

网络安全实训Day16

网络空间安全实训-渗透测试 漏洞扫描 定义 扫描和探测目标范围内的主机存在哪些安全漏洞&#xff0c;或扫描目标范围内的那些主机存在某个指定的漏洞 漏扫工具 AWVS APPScan MSF 使用MSF扫描漏洞并利用 1.搜索需要的攻击模块 search ms17-010 2.使用攻击模块 use 模块名称…

苏州相融大厦安装部署火眼视频图像早期火灾报警系统

2024年3月&#xff0c;苏州高铁数金公司、火眼消防技术有限公司与招商积余物业联合在相融大厦进行了火眼视频图像早期火灾报警系统的部署和测试工作&#xff0c;测试效果良好。体现招商积余对持续推进消防安全工作的高度重视。 相融大厦是火眼消防总部注册和苏州研发中心所在地…

OpenCV直方图计算

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV实现直方图均衡 下一篇 :OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 cv::split 将图像划分…

网络安全实训Day24(End)

写在前面 并没有完整上完四个星期&#xff0c;老师已经趁着清明节假期的东风跑掉了。可以很明显地看出这次持续了“四个星期”实训的知识体系并不完整&#xff0c;内容也只能算是一次基础的“复习”。更多的内容还是靠自己继续自学吧。 网络空间安全实训-渗透测试 文件包含攻击…

用 C 语言进行大模型推理:探索 llama2.c 仓库(一)

文章目录 前提有关huggingface社区chinese-baby-llama2llama2.cexport.py读取模型信息重建模型对重建出的模型初始化权重导出run.c要求的.bin文件 tokenizer.py 一些思考参考链接 前提 最近发现了一个只用c语言就可以推理大模型的仓库llama2.c&#xff0c;作者是openAI的员工。…

把私有数据接入 LLMs:应用程序轻松集成 | 开源日报 No.236

run-llama/llama_index Stars: 29.9k License: MIT llama_index 是用于 LLM 应用程序的数据框架。 该项目解决了如何最佳地利用私有数据增强 LLMs&#xff0c;并提供以下工具&#xff1a; 提供数据连接器&#xff0c;以摄取现有的数据源和各种格式&#xff08;API、PDF、文档…

vite加密打包插件(vite-plugin-javascript-obfuscator)选项(option)详解

本文主要介绍vite加密打包插件(vite-plugin-javascript-obfuscator)选项(option)。 目录 一、选项(option)1. compact2. config3. controlFlowFlattening4. controlFlowFlatteningThreshold5. deadCodeInjection6. deadCodeInjectionThreshold7. debugProtection8.debugProtect…

【每日刷题】Day23

【每日刷题】Day23 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 2. 链表的回文结构_牛客题霸_牛客网 …

MySQL从入门到高级 --- 2.DDL基本操作

文章目录 第二章&#xff1a;2.基本操作 - DDL2.1 数据库的常用操作创建数据库选择要操作的数据库删除数据库修改数据库编码 2.2 表结构的常用操作创建表格式查看当前数据库的所有表名称查看指定某个表的创建语句查看表结构删除表 2.3 修改表结构添加列修改列名和类型删除列修改…

python之excel加工处理小案例一则

一、工具用途 工作中&#xff0c;需要对各类excel进行加工处理&#xff0c;当表和字段比较多时&#xff0c;关联条件又有多个&#xff0c;每次通过execl的vlookup之类的关联公式手工可以解决工作需求&#xff0c;但一般耗时较长&#xff0c;且人工统计匹配也存在出错的情况。 …

cnpm安装

npm install -g cnpm --registryhttps://registry.npmmirror.com # 注册模块镜像 npm set registry https://registry.npmmirror.com // node-gyp 编译依赖的 node 源码镜像 npm set disturl https://npmmirror.com/dist // 清空缓存 npm cache clean --force // 安装c…