基于JWT(JSON Web Token)的工程引入与落地实践

2023-11-07

1、JWT认识

1.1 什么是JWT ?

JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌

1.2 透明令牌与自包含令牌

在这里插入图片描述

2、JWT起飞

2.1 JWT的用处

1、多web服务器下实现无状态分布式身份验证。
2、JWT 最重要的作用就是对 token信息的防伪。
在这里插入图片描述

2.2 JWT的原理

一个JWT由三个部分组成:JWT头、有效载荷、签名哈希,最后由这三者组合进行base64编码得到JWT。

2.3 JWT的结构

在这里插入图片描述从图中可以看到,JWT为一个很长的字符串,一共是三段。
分别是头、有效载荷、签名哈希。

2.3.1 JWT头

JWT头部分是一个描述JWT元数据的JSON对象,如下所示。

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

其中,

  • alg表示签名使用的算法,默认为 HMAC SHA256 ,简称HS256;
  • typ表示令牌类型,JWT令牌统一写为JWT;
    最后,使用Base64Url将上述对象转换为字符串保存。
    Base64Url算
    JWT头和有效载荷序列化的算法都用到了Base64URL。该算法和常⻅Base64算法类似,稍有差别。
    作为令牌的JWT可以放在URL中(例如api.example/?token=xxx)。 Base64中用的三个字符是"+“,”/“和”=“,由于在URL中有特殊含义,因此Base64URL中对他们做了替换:”=“去掉,”+“用”-“替换,”/“用”_"替换,这就是Base64URL算法。
    注意:base64编码,并不是加密,只是把明文信息变成了不可⻅的字符串。但是其实只要用一些工具就可以把base64编码解成明文,所以不要在JWT中放入涉及私密的信息。

2.3.2 有效载荷

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。JWT指定七个默认字段供选择。

sub: 主题
iss: jwt签发者
aud: 接收jwt的一方
iat: jwt的签发时间
exp:jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

除以上默认字段外,我们还可以自定义私有字段,如下例:

{
	"userName":"Java3q",
	"age":"x",
	"address":"xxx"
}

默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。JSON对象也使用Base64 URL算法转换为字符串保存。

2.3.3 签名哈希

签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。
首先,需要指定一个密钥(secret)。该密钥仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下原理生成签名。

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

代码中的签名原理实现逻辑如下:

@Override
    public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) {
        Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty.");
        Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures.  If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead.");
        byte[] bytes = TextCodec.BASE64.decode(base64EncodedSecretKey);
        return signWith(alg, bytes);
    }

在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象。

3、JWT落地

3.1 JWT的用法

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。当跨域时,也可以将JWT放置于POST请求的数据主体中。

3.2 JWT的实践

3.2.1 创建工程

新建maven工程,引入下面依赖包

<dependencies>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

直接在单元测试包中写下面两个就行,也方便测试。

3.2.2 生成token(含截图)

/**
 * Java3q
 */
public class JwtGeneToken {

    private static long tokenExpiration = 24*60*60*1000;  //毫秒

    private static String tokenSignKey = "Java3qTest";//密钥
    
    /**
     * 生成token
     */
    @Test
    public void testCreateToken() {
        String token = Jwts.builder()
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")

                .setSubject("Java3q_jwt")
                .setIssuer("Java3q")
                .setAudience("Java3q_fence")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .setNotBefore(new Date(System.currentTimeMillis() + 20))
                .setId(UUID.randomUUID().toString())

                .claim("userName","java3q")
                .claim("age",1)

                .signWith(SignatureAlgorithm.HS256,tokenSignKey)
                .compact();//toString

        System.out.println("生成的token为:"+token);


    }

}

在这里插入图片描述

3.2.3 解析token(含截图)

/**
 * Java3q
 */
public class JwtParseToken {

    private static long tokenExpiration = 24*60*60*1000;  //毫秒

    private static String tokenSignKey = "Java3qTest";//密钥


    /*
    解析token
     */
    @Test
    public void testGetUserInfo() {

        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKYXZhM3Ffand0IiwiaXNzIjoiSmF2YTNxIiwiYXVkIjoiSmF2YTNxX2ZlbmNlIiwiaWF0IjoxNjU4NTYwOTY4LCJleHAiOjE2NTg2NDczNjgsIm5iZiI6MTY1ODU2MDk2OCwianRpIjoiZDU0YjQ2YzMtMThhNy00NTQxLWIxODAtMmQzODhlYjYwZTAxIiwidXNlck5hbWUiOiJqYXZhM3EiLCJhZ2UiOjF9.V1o1rGBlmRZhfRXHp7Hment7yQeCuDRWPa8EUN7huNo";

        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);

        String typ = (String)claimsJws.getHeader().get("typ");
        String alg = (String)claimsJws.getHeader().get("alg");

        System.out.println("typ:"+typ);
        System.out.println("alg:"+alg);


        //获取默认载荷数据
        Claims claims = claimsJws.getBody();
        String subject = claims.getSubject();
        String issuer = claims.getIssuer();
        String audience = claims.getAudience();
        Date issuedAt = claims.getIssuedAt();
        Date expiration = claims.getExpiration();
        Date notBefore = claims.getNotBefore();
        String id = claims.getId();

        System.out.println(subject+"  "+issuer+"  "+audience+"  "+issuedAt+"  "+expiration+"  "+notBefore+"  "+id);

        //获取自定义载荷数据
        String userName = (String)claims.get("userName");
        Integer age = (Integer)claims.get("age");
        System.out.println("userName:"+userName);
        System.out.println("age:"+age);


    }

}

在这里插入图片描述

4、JWT展望

1、JWT默认不加密,但可以加密。生成原始令牌后,可以使用该令牌再次对其进行加密。
2、当JWT未加密时,一些私密数据无法通过JWT传输。
3、JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。
4、JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。
5、JWT本身包含认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。为了减少盗用,JWT的有效期不宜设置太长。对于某些重要操作,用户在使用时应该每次都进行身份验证。
6、为了减少盗用和窃取,JWT不建议使用HTTP协议来传输代码,而是使用加密的HTTPS协议进行传输。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于JWT(JSON Web Token)的工程引入与落地实践 的相关文章

  • 插入最大日期(独立于数据库)

    在我的本地设置中 我使用一个简单的 H2 数据库 托管 解决方案将有另一个 类似但不相同 数据库 我需要将最大可能日期插入到日期时间列中 我尝试使用 Instant MAX 但是 这会导致列中出现 169104626 12 11 20 08
  • 如何创建一个显示 Spinners 的 x 和 y 值的表格?

    我想创建一个位于图表右侧的表格 其中显示 2 列 x 和 y 值已输入到xSpin and ySpin旋转器 我已经画了一张我想要桌子放置的位置的图 我尝试过在网格窗格布局中使用文本框来创建表格并将值直接输入到文本框网格中 但是我无法将它们
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • 如何安全地解决这个 Java 上下文类加载器问题?

    我的数百名用户中只有一位在启动我的 Java 桌面应用程序时遇到问题 他只有大约三分之一的时间开始 另外三分之二的时间在启动时抛出 NullPointerException Exception in thread AWT EventQueu
  • 我可以使用子接口重新编译公共 API 并保持二进制兼容性吗?

    我有一个公共 API 在多个项目中多次使用 public interface Process
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 如何在selenium服务器上提供自定义功能?

    我知道可以通过某种方法获得一些硒功能 其中之一如下 driver getCapabilities getBrowserName 它返回浏览器名称的值 但如果它指的是一个可用的方法 如果我没有误解的话 这似乎与自定义功能有关 就像我的意思是
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • Jersey 客户端请求中未设置 Content-Length-Header

    我正在使用 Jersey Client 访问网络服务 如下所示 response r accept MediaType TEXT PLAIN TYPE header content length 0 post String class 其中
  • 如何知道抛出了哪个异常

    我正在对我们的代码库进行审查 有很多这样的陈述 try doSomething catch Exception e 但我想要一种方法来知道 doSomething 抛出了哪个异常 在 doSomething 的实现中没有 throw 语句
  • 如何在JSTL中调​​用java方法? [复制]

    这个问题在这里已经有答案了 这可能是重复的问题 我只想调用不是 getter 或 setter 方法的方法例如 xyz 类的 makeCall someObj stringvalue Java类 Class XYZ public Strin
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • 我可以创建自定义 java.* 包吗?

    我可以创建一个与预定义包同名的自己的包吗在Java中 比如java lang 如果是这样 结果会怎样 这难道不能让我访问该包的受保护的成员 如果不是 是什么阻止我这样做 No java lang被禁止 安全管理器不允许 自定义 类java
  • 替换后增量

    我自己已经有一个问题了 但我想扩展它后增量示例 https stackoverflow com questions 51308967 post increment with example char a D int b 5 System o
  • HQL Hibernate 内连接

    我怎样才能在 Hibernate 中编写这个 SQL 查询 我想使用 Hibernate 来创建查询 而不是创建数据库 SELECT FROM Employee e INNER JOIN Team t ON e Id team t Id t
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • hashcode 的默认实现为以相同方式构造的对象返回不同的值

    我在这里编写一个示例代码 public class Test private int i private int j public Test TODO Auto generated constructor stub public Test
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import

随机推荐

  • 电磁兼容测试分析软件软件,电磁兼容测试方案的主要应用

    汽车制造商必须保证汽车的无用杂散处于规定界限范围内 EMI 同时 要保证汽车能够抵抗来自外部和内部源的骚扰 EMS 例如电视发射机 移动基站或其他电子汽车组件 作为该领域的全球领导者 罗德与施瓦茨提供高效的测试解决方案 确保您的产品符合电磁
  • 恢复hosts文件

    因破解GoLand需要 得修改hosts文件 打开目录 C Windows System32 drivers etc 尼玛 hosts文件怎么没有了 什么局面 手动恢复hosts文件 窗口键 X 运行 cmd打开控制台 输入命令 for f
  • MySQL的bin目录去哪里了

    方法一 点开始 运行 输入 services msc 在打开的 服务管理器 中找到mysql并双击 会弹出来个属性框框 常规 选项卡里面有个 执行路径 从这个路径你就可以看到它的bin目录在哪 很多人没有找到框 再次更新一下 方法二 打开任
  • 小米造车150天:烈火烹油第一枪

    贾浩楠 发自 凹非寺量子位 报道 公众号 QbitAI 小米官宣造车 小米开启智能驾驶招聘 小米7737万美元收购深动科技 小米汽车正式完成工商注册 落户北京亦庄 入局5个月 这是小米造车的一系列进展 还没算上2万多简历 300人团队 大量
  • IOS上架流程详解,包含审核避坑指南!

    准备 开发者账号 完工的项目 上架步骤 一 创建App ID 二 创建证书请求文件 CSR文件 三 创建发布证书 CER 四 创建Provisioning Profiles配置文件 PP文件 五 在App Store创建应用 六 打包上架
  • ABP框架 - 介绍

    文档目录 本节内容 简介 一个快速示例 其它特性 启动模板 如何使用 简介 我们总是对不同的需求开发不同的应用 但至少在某些层面上 一次又一次地重复实现通用的和类似的功能 如 授权 验证 异常处理 日志 本地化 数据库连接管理 设置管理 审
  • C++ 实现Kafka TLS双向加密

    C 实现Kafka TLS双向加密 基本概念 非对称加密 CA TLS双向加密过程 TLS 双向认证流程 代码 基本概念 Kafka TLS双向加密包含的知识涉及到对称加密 非对称加密 Kafka CA 数字证书 本文采用C librdka
  • (python代码+讲解)重叠社区发现EAGLE层次算法的实现

    EAGLE是一种基于最大团聚类的层次聚类算法 用来揭示网络的层次化和层次化社区结构 该算法采用一种聚类框架 来处理最大派系 1 算法的实现 首先用Bron Kerbosch算法找到网络中的最大派系 要设置一个阈值k来丢弃所有小于K的最大派系
  • RS232中RTS和CTS的作用

    RS232中RTS和CTS的作用 转载 2011年12月26日 23 21 06 1149 0 0 RS232中RTS和CTS的作用 问 以前挺明白的 今天一下子觉得以前的理解都不对了 以下三种解释哪个对呢 解释一 RTS 终端我已经准备就
  • Spring Cloud(七):服务网关zuul过滤器

    上文介绍了Zuul的基本使用与路由功能 本文接着介绍Zuul的核心概念 Zuul过滤器 filter Zuul的功能基本通过Zuul过滤器来实现 类比于Struts的拦截器 只是Struts拦截器用到责任链模式 Zuul则是通过Filter
  • 云计算是被逼出来的

    author skate time 2010 05 26 云计算是被逼出来的 1 云计算是被逼出来的 云计算是被逼出来的 计算量越来越大 数据越来越多 越来越要动态 越来越要实时 越来越需要结构化 光有服务器 光有PC客户端已经不够了 所以
  • 集合泛型为对象,根据对象的某个属性进行排序

    根据集合里的深度 排序集合 Collections sort irFldsltpvMList new Comparator 为集合名 为实体类对象 Override public int compare IrFldsltpvM o1 IrF
  • java的两种比较器

    比较算法 日常生活中 如果想比较两个数的大小 可采用做差的方式 做差结果的正负可用来判断两个数的大小 假设A B C 若整数C gt 0 说明 A gt B 若整数C 0 说明 A B 若整数C lt 0 说明 A lt B java的两种
  • 求子数组问题

    子数组问题分为三类 1 连续子数组 2 非连续子数组 3 可连续也可以不连续 这三类问题的解决办法一般都是循环或者动态规划 尝试了dfs算法 结果把自己给绕进去了 一 最大升序问题 属于第三类 参考 https www cnblogs co
  • Controlling Font Size With Javascript 兼容主流浏览器

  • 简单的递归组件示例-vue3

    1 呈现效果 2 代码实现 2 1 src App vue 代码
  • 送呆萌的她一个皮卡丘(Python实现)

    目录 1 呆萌的她 2 思维需要革新 3 送她的一个漂亮皮卡丘 4 Python完整代码奉上 1 呆萌的她 又是一季春风暖阳下 你是一湾一湾羞涩的春波 静静感受着 你垂下的枝膊 在我的脸上轻轻抚摸 一对春燕 低低掠过 涟漪乍起 是你浅浅的笑
  • 计算机的性能公式

    cpu执行时间 简称CPU时间 表示执行某一任务在CPU上所花费的时间 不包括等待I O或运行其他程序的时间 程序的cpu执行时间 cpu时钟周期数 时钟周期时间 cpu时钟周期数 主频 要想缩短cpu执行时间 最简单的方法就是缩短cpu的
  • 连表查询可以跟多个条件

    连表查询时后面条件可以跟多个条件 select from tabA a tabB b where a userID b userID and a userName b userName select from tabA a left joi
  • 基于JWT(JSON Web Token)的工程引入与落地实践

    JWT从认识 起飞到落地 1 JWT认识 1 1 什么是JWT 1 2 透明令牌与自包含令牌 2 JWT起飞 2 1 JWT的用处 2 2 JWT的原理 2 3 JWT的结构 2 3 1 JWT头 2 3 2 有效载荷 2 3 3 签名哈希