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.mfbz.cn/a/579341.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习之基于YOLOv5的山羊行为识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于YOLOv5的山羊行为识别系统是一个结合了深度学习和目标检测技术的项目&#xff0c;旨在通过图像或视频实现对山羊…

DELL PowerEdge服务器通过iDRAC升级BIOS遇到的问题

本文对PowerEdge 12G系统&#xff0c;也就是iDRAC 7版本升级BIOS中遇到的几个问题做个总结&#xff0c;对于其他版本理论上应该也是适用的。如果还遇到其他问题&#xff0c;可以添加VX&#xff0c;VX号为 StorageExpert 进行进一步的分析探讨。 第一个问题&#xff0c;成功下载…

C#调用skiasharp实现绘制并拖拽图形

SkiaSharp是基于.net的跨平台二维图形库&#xff0c;封装的谷歌的Skia库&#xff0c;SkiaSharp支持在以下平台或运行时中使用&#xff0c;能够在图片中绘图&#xff0c;也提供控件在Winform、WPF等使用。本文学习skiasharp在Winform的基本用法&#xff0c;并参照参考文献5实现绘…

【Unity动画系统】详解Root Motion动画在Unity中的应用(一)

Root Motion动画与普通动画的区别 普通动画&#xff1a;动画文件里记录的是物体的绝对坐标和方向&#xff0c;在播放动画时&#xff0c;Unity会根据Animation中记录的值&#xff0c;直接修改游戏对象的坐标和方向&#xff0c;每一帧的坐标和方向都是通过插值计算得出来的&…

【Camera KMD ISP SubSystem笔记】Request 流转与Bubble机制

ISP中断类型 SOF: 一帧图像数据开始传输 EOF: 一帧图像数据传输完成 REG_UPDATE: ISP寄存器更新完成(每个reg group都有独立的这个中断) EPOCH: ISP某一行结尾(默认20)就会产生此中断 BUFFER DONE: 一帧图像数据ISP完全写到DDR了 管理Isp request的几个List st…

锂电池SOH预测 | 基于CNN的锂电池SOH预测(附matlab完整源码)

锂电池SOH预测 锂电池SOH预测完整代码锂电池SOH预测 锂电池的SOH(状态健康度)预测是一项重要的任务,它可以帮助确定电池的健康状况和剩余寿命,从而优化电池的使用和维护策略。 SOH预测可以通过多种方法实现,其中一些常用的方法包括: 容量衰减法:通过监测电池的容量衰减…

AMBA-CHI协议详解(二)

《AMBA 5 CHI Architecture Specification》 文章目录 2.1 Channels综述2.2 Channel域段2.2.1 request fields2.2.2 Response fields2.2.3 Snoop request fields2.2.4 Data fields 2.3 事务结构2.3.1 Read transactions2.3.1.1 Allocating Read2.3.1.2 Non-allocating Read 2.…

字符串类型漏洞之updatexml函数盲注

UPDATEXML 是 MySQL 数据库中的一个函数&#xff0c;它用于对 XML 文档数据进行修改和查询。然而&#xff0c;当它被不当地使用或与恶意输入结合时&#xff0c;它可能成为 SQL 注入攻击的一部分&#xff0c;从而暴露敏感信息或导致其他安全漏洞。 在 SQL 注入攻击中&#xff0…

通过Cmake官网下载.gz文件安装最新版本的CMAKE、适用于debian

1.前往官网下载最新版本debian https://cmake.org/download/ 2.选他 3. 通过XFTP传输到服务器 4. 解压文件 #cd 进入对应目录&#xff0c;然后执行下面命令解压 $ tar -zxvf cmake-3.29.2.tar.gz5.执行这个文件 $ ./bootstrap6.完成之后再执行这个 $ make7.然后&#xff…

C语言--贪吃蛇小游戏

目录 一、Win32API介绍 1.1Win32API 1.2控制台程序 1.3控制台屏幕上的坐标COORD 1.4GetStdHandle 1.5GetConsoleCursorInfo 1.6 CONSOLE_CURSOR_INFO 1.7 SetConsoleCursorInfo 1.8SetConsoleCursorPosition 1.9GetAsyncKeyState 二、贪吃蛇游戏设计与分析 2.1地图 …

双重注意力模块 DoubleAttention | A2-Nets: Double Attention Networks

论文名称&#xff1a;《 A 2 A^2 A2-Nets: Double Attention Networks》 论文地址&#xff1a;https://arxiv.org/pdf/1810.11579.pdf 学习捕捉远距离关系对于图像/视频识别是基础性的。现有的CNN模型通常依靠增加深度来建模这些关系&#xff0c;这在很大程度上效率低下。在这…

数字旅游打造个性化旅行体验,科技让旅行更精彩:借助数字技术,旅行者可以定制专属旅行计划,享受个性化的旅行体验

目录 一、引言 二、数字旅游的兴起与发展 三、数字技术助力个性化旅行体验 1、智能推荐系统&#xff1a;精准匹配旅行者需求 2、定制化旅行计划&#xff1a;满足个性化需求 3、实时互动与分享&#xff1a;增强旅行体验 四、科技提升旅行便捷性与安全性 1、移动支付与电…

boot https ssl 使用http协议访问报错

在springboot中配置ssl以后&#xff0c; 再次使用http访问对应的接口就会报错 可以考虑如下设置&#xff0c;将http访问的端口重定向到https对应的端口 import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util…

图像处理ASIC设计方法 笔记18 轮廓跟踪算法的硬件加速方案

目录 1排除伪孤立点&#xff08;断裂链表&#xff09;方法1 限制链表的长度方法2 增加判断条件排除断裂链表方法3 排除不必要跟踪的轮廓&#xff08;推荐用这个方法&#xff09; P129 轮廓跟踪算法的硬件加速方案 1排除伪孤立点&#xff08;断裂链表&#xff09; 如果图像中某…

探索开源的容器引擎--------------Docker容器操作

目录 一、Docker 容器操作 1.1容器创建 1.2查看容器的运行状态 1.3启动容器 1.4创建并启动容器 1.4.1当利用 docker run 来创建容器时&#xff0c; Docker 在后台的标准运行过程是&#xff1a; 1.4.2在后台持续运行 docker run 创建的容器 1.4.3创建容器并持续运行容器…

Pytorch基础:torch.load_state_dict()方法在加载时不会检查类型

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 笔者在使用torch.nn.module的load_state_dict中出现了一个问题&#xff0c;一个被注册的张量在加载后居然没有变化&#xff0c;一开始以为是加载出现了问题&#…

Kafka 3.x.x 入门到精通(07)——Java应用场景——SpringBoot集成

Kafka 3.x.x 入门到精通&#xff08;07&#xff09;——Java应用场景——SpringBoot集成 4. Java应用场景——SpringBoot集成4.1 创建SpringBoot项目4.1.1 创建SpringBoot项目4.1.2 修改pom.xml文件4.1.3 在resources中增加application.yml文件 4.2 编写功能代码4.2.1 创建配置…

debian配置BIND DNS服务器

前言 局域网内有很多台主机&#xff0c;IP难以记忆。 而修改hosts文件又难以做到配置共享和统一&#xff0c;需要一台内网的DNS服务器。 效果展示 这里添加了一个域名hello.dog&#xff0c;将其指向为192.168.1.100。 同时&#xff0c;外网的域名不会受到影响&#xff0c;…

基于粒子滤波器的电池剩余使用寿命计算matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 粒子滤波器基础 4.2 电池剩余使用寿命建模与预测 4.3 粒子滤波器在电池寿命预测中的应用 5.完整工程文件 1.课题概述 基于粒子滤波器的电池剩余使用寿命计算。根据已知的数据&#xff0c;预测未来…

前端框架编译器之模板编译

编译原理概述 编译原理&#xff1a;是计算机科学的一个分支&#xff0c;研究如何将 高级程序语言 转换为 计算机可执行的目标代码 的技术和理论。 高级程序语言&#xff1a;Python、Java、JavaScript、TypeScript、C、C、Go 等。计算机可执行的目标代码&#xff1a;机器码、汇…