JWT详解和使用(jjwt)

article/2025/11/9 16:00:25

JWT详解和使用

JWT是啥

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

下列场景中使用JSON Web Token是很有用的:

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

JWT怎么用

在登录时,服务器端获取用户的信息等,根据需求(如expiration等)生成一个JWT返回给客户端。客户端每次请求时,带上该JWT,服务器端只需要对该JWT进行解密,就可以得知该JWT是否有效、用户的信息(注意不能有敏感信息)等。这个过程服务端不需要存储JWT的内容(不同于之前类似Session id的那种token),只需要对JWT进行加解密操作。

ps.之前我使用的类似Session id的token是指用随机生成的字符串作为token(同时作为缓存的key),将用户信息json化(或其他序列化方式)缓存。token返回给客户端,客户端每次请求时带上token,服务器就可以从缓存中读出用户信息,减少了数据库的压力(?)。

JWT的结构

874963-20180709124807031-664967381.png
如图,JWT由三个部分组成,之间由一个“.”连接

  • Header/头部(我来组成头部x)
  • Payload/载荷
  • Signature/签名

下面具体介绍这三个部分

Header/头部

头部一般由两个部分组成,token的类型和使用的算法。形式如下:

{"alg":"HS256","typ":"JWT","zip":"...","YOUR_KEY":"YOUR_VALUE"
}

当然还可以增加一些如zip(指示压缩方法)等自定义的字段。

Payload(Body)/载荷

payload部分是JWT存储信息的部分,包含着Claims(声明),其实就是存储的的数据。

一般声明分为以下三种类型:

  • Registered claims:预定义的声明,如:
    • iss:issuer 发布者的URL地址
    • sub:subject JWT面向的用户,不常用
    • aud:audience 接受者的URL地址
    • exp:expiration JWT失效的时间(Unix timestamp)
    • nbf:not before 该时间前JWT无效(Unix timestamp)
    • iat:issued at JWT发布时间(Unix timestamp)
    • jti:JWT ID
  • Public claims:公开字段(也不知道干啥的)
  • Private claims:自定义私有字段(可以在这个字段里定义要传递的用户信息等)不能在此字段传递加密的信息,这部分采用对称加密方式,传输内容可以被解开。
eg.
{"sub":"1234567890","name":"John Doe","admin":true
}

Signature/签名

签名部分的生成公式如下

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

即base64编码的header和payload,加上一个秘钥。

签名的用途显而易见就是验证前面部分的内容是否有被篡改(因为前面是对称加密的,容易修改)。

使用jjwt生成JWT

这里使用了一个开源项目jjwt(https://github.com/jwtk/jjwt)来实现。当然JWT的实现也不难,这里因为懒(以及菜)就选择用这个开源项目了。

Installation/部署

首先需要在Maven中添加dependencies,如下

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.10.7</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.10.7</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.10.7</version><scope>runtime</scope>
</dependency>

我使用的环境是IDEA,设置了Auto-import,所以添加了之后稍等一下就发现红线消失,依赖问题解决了。

Maven真好用 IDEA真聪明(小声逼逼

Quickstart/快车

一个JWS(signed JWT)的创建过程大致分为以下三步:

  1. 构建一个有默认载荷的JWT
  2. 用秘钥签名这个JWT(秘钥必须满足HMAC-SHA-256算法)
  3. 打包JWT成一个字符串

贴一下代码

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;// We need a signing key, so we'll create one just for this example. Usually
// the key would be read from your application configuration instead.
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();

注意到第8行,这里用助手函数生成了一个随机的满足加密算法要求的key,在正常使用中,需要自己定义一个秘钥。

输出会得到一个类似如下的字符串,这个就是生成的JWT,可以看到Header、Payload和Signature三个部分

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.1KP0SsvENi7Uz1oQc07aXTL7kpQG5jBNIybqr60AlD4

那么如何验证这个JWT是否有效呢

贴代码

try {Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);//OK, we can trust this JWT} catch (JwtException e) {//don't trust the JWT!
}

OK,JWT生成、验证的过程就这么简单!

接下来开始正式使用部分的介绍

生成JWT

先贴代码

        byte[] secret = "2162d3e65a421bc0ac76ae5acfe29c650becb73f2a9b8ce57941036331b1aaa8".getBytes();SecretKey key = Keys.hmacShaKeyFor(secret);String jws = Jwts.builder().setHeaderParam("kid", "123456").setSubject("111").setIssuer("ameow").setNotBefore(new Date()).claim("weisha", "wozhidaole").signWith(key).compact();

首先是我比较关心的key的部分。查阅文档(https://github.com/jwtk/jjwt )可以知道,JWT对key的长度是有要求的,以这里SHA-256为例,就需要256位的key。具体加密方法对应的key要求可以在文档中查到,不多叙述(因为不会)。

这里我想选择一个字符串“hello”作为key,于是我需要生成一个对应的SHA-256加密的串,这里可以用Java实现SHA-256加密,也可以使用在线的SHA-256生成工具直接生成这个串,然后直接换成byte形式,用jjwt提供的助手方法转换成key。(可能这样会不太安全?)

然后就是JWS的部分,用Jwts.builder(),然后就是set里面的内容,最后sign和compact,就可以得到生成的JWT。

如果要生成自定义的claim,可以采用以下的方法

Claims claims = Jwts.claims();populate(claims); //implement meString jws = Jwts.builder().setClaims(claims)// ... etc ...

其他部分暂时还没有接触到,碰到再研究。

读取JWT

简单几步

  1. 用Jwts.parser()创建一个JwtParser对象
  2. 指定要使用的秘钥setSigningKey()
  3. 调用parseClaimsJws()方法
  4. 用try/catch块包裹这部分内容,方便jjwt处理异常

如果要获取里面的内容,可以采用以下代码

Jws<Claims> jwsR;try {jwsR = Jwts.parser().setSigningKey(key).parseClaimsJws(jws);System.out.println(jwsR);System.out.println(jwsR.getBody().get("weisha"));} catch (JwtException ex) {System.out.println("???");}

输出如下(1是传入的JWT,2是JWT解释出的内容,3是获取到的Body中的weisha字段中的内容)

eyJraWQiOiIxMjM0NTYiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMTEiLCJpc3MiOiJhbWVvdyIsIm5iZiI6MTU3MTEyMjI4MCwid2Vpc2hhIjoid296aGlkYW9sZSJ9.nOvpsOZ93bmdjBgRRADoWJhTAJ-QOrumHtFgqCd6V9CAafZe0nzXCBxbw2YmsVKLW2i2SGy0FbgZjBtt_H8Q3w
header={kid=123456, alg=HS512},body={sub=111, iss=ameow, nbf=1571122280, weisha=wozhidaole},signature=nOvpsOZ93bmdjBgRRADoWJhTAJ-QOrumHtFgqCd6V9CAafZe0nzXCBxbw2YmsVKLW2i2SGy0FbgZjBtt_H8Q3w
wozhidaole

最后

这篇博客没有提到加密方面的细节,是因为我对安全方面不太了解,这方面还有待学习。如果有安全方面需求,可以查阅以下的ref。

Ref:

https://www.cnblogs.com/cjsblog/p/9277677.html

https://github.com/jwtk/jjwt

https://jwt.io/


http://chatgpt.dhexx.cn/article/DEsGwygF.shtml

相关文章

JJWT 实现JWT

1什么是JJWT JJWT 是一个提供端到端的 JWT 创建和验证的 Java 库。永远免费和开源 (Apache License&#xff0c;版本2.0)&#xff0c;JJWT 很容易使用和理解。它被设计成一个以建筑为中心的流畅界面&#xff0c;隐藏了它的大部分复杂性。 2JJWT快速入门 2.1token的创建 2.1…

什么是JWT?

在HTTP接口调用的时候&#xff0c;服务端经常需要对调用方做认证&#xff0c;以保证安全性。一种常见的认证方式是使用JWT(Json Web Token)&#xff0c;采用这种方式时&#xff0c;经常在header传入一个authorization字段&#xff0c;值为对应的jwt_token&#xff0c;或者也有图…

JWT的学习和JJWT的使用

1.什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一个开放的行业标准&#xff0c;它定义了一种简介的&#xff0c;自包含的协议格式&#xff0c;用于在通信双方传递json对象&#xff0c;传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或者使用RSA的公…

JWT详解

本文从本人博客搬运&#xff0c;原文格式更加美观&#xff0c;可以移步原文阅读&#xff1a;JWT详解 JWT简介 1.什么是JWT 在介绍JWT之前&#xff0c;我们先来回顾一下利用token进行用户身份验证的流程&#xff1a; 客户端使用用户名和密码请求登录服务端收到请求&#xff…

JWT详解、JJWT使用、token 令牌

前言 在正式讲解JWT之前&#xff0c;我们先重温一下用户身份认证相关的一些概念&#xff1a; 有状态登录&#xff08;session认证&#xff09; 服务器当中记录每一次的登录信息&#xff0c;从而根据客户端发送的数据来判断登录过来的用户是否合法。 缺点&#xff1a; 每个用…

Java的JJWT实现JWT

1 什么是 JJWT JJWT 是一个提供端到端的 JWT 创建和验证的 Java 库。永远免费和开源 (Apache License&#xff0c;版本2.0)&#xff0c;JJWT 很容易使用和理解。它被设计成一个以建筑为中心的流畅界面&#xff0c;隐藏了它的大部分复杂性。 2 token 的创建 2.1 引入依赖 &l…

解决Red Hat虚拟机与主机网络不通

虚拟机版本&#xff1a;Red Hat Enterprise Linux 7 64 位 安装&#xff1a;自定义安装&#xff0c;带GUI的服务器&#xff0c;创建图形化界面 创建完毕后发现网络ping不通&#xff0c;经过查阅各种资料&#xff0c;在同事的帮助下终于解决。做一个记录。 1、VMware网络配置。…

虚拟机VMware和宿主机连接

文章目录 一、NAT连接1.查看宿主机IP地址2.设置VMnet8信息2.设置虚拟机模式3.设置虚拟网络4.设置虚拟机内系统IP&#xff08;Centos8.2为例&#xff09;4.1.图形化操作4.1.1DHCP4.1.2静态IP4.1.3 重启网卡&#xff08;修改网卡信息后&#xff09; 5.测试5.1.宿主机ping虚拟机5.…

VMware虚拟机三种网络连接模式详解

VMware虚拟机三种网络连接模式详解 Vmware提供了三种网络工作模式&#xff0c;分别是&#xff1a;&#xff08;1&#xff09;Bridged&#xff08;桥接模式&#xff09;&#xff1b;&#xff08;2&#xff09;NAT&#xff08;网络地址转换模式&#xff09;&#xff1b;&#xf…

虚拟机与主机之间通信

1.bridged(桥接方式&#xff0c;默认使用vmnet0虚拟网卡)&#xff1a; 选择这种模式&#xff0c;虚拟机等同于网络内的一台物理主机&#xff0c;可对手动设置IP&#xff0c;子网掩码。DNS&#xff0c;且IP地址要和主机的IP在同一网段内。这样。虚拟机就和主机如同连在一个HUB上…

虚拟机的几种网络连接方式

系列运维 文章目录 系列运维前言一、几种网络连接方式各是什么&#xff1f;二、网络连接的差异性总结 前言 VirtualBox中有4种网络连接方式&#xff1a; NAT Bridged Adapter Internal Host-only Adapter VMWare中有三种&#xff0c;VirtualBox只是比VMWare多了Internal方式。…

主机、虚拟机、开发板之间网络连接设置

最近在玩开发板&#xff0c;主机使用的无线网卡&#xff0c;开发板与主机网线直连&#xff0c;现在开发板想使用tftp直接从虚拟机下载镜像等文件&#xff0c;偶尔又需要虚拟机从主机下载文件&#xff0c;虚拟机有时候又需要网络&#xff0c;经过一番折腾算是调试成功。 1.主机…

vmware虚拟机与主机共享网络

我的虚拟机总是各种连不上网&#xff0c;每次都要折腾一番。现在我把虚拟机连不上网的原因总体排查一下&#xff0c;按照流程一步步来&#xff0c;基本上可以解决大部分人的问题。 首先&#xff0c;在VMware的编辑->虚拟网络编辑器重新建立&#xff2e;&#xff21;&#xf…

Virtualbox虚拟机与主机相互访问

刚从vmware切换到Virtualbox有些地方还是不太熟悉。网络连接这块就被卡了一下&#xff0c;后来发现其实很简单&#xff0c;是我想多了。 环境 主机&#xff1a; archlinux 虚拟机&#xff1a;windows 10 软件版本&#xff1a;VirtualBox 6.1 理论上这些环境不影响&#xff0…

虚拟机和主机无法连接

vm网络配置&#xff1a;https://www.cnblogs.com/aeolian/p/8882790.html 一、首先查看自己的虚拟机服务有没有开启&#xff0c;选择电脑里面的服务查看&#xff1b; 1.计算机点击右键选择管理 2.进入管理选择VM开头的服务如果没有开启的话就右键开启 二、虚拟机服务开启后就…

虚拟机和主机的网络访问

本人的问题是主机可以ping虚拟机&#xff0c;虚拟机可以正常访问端口&#xff0c;主机不能访问虚拟机端口&#xff0c;然后就进行各种问题的排查&#xff0c;一开始把所有的防火墙都关了还不行&#xff0c;所以来到了windows主机虚拟网卡这里设置&#xff0c;使用了手动设置虚拟…

VMwareWorkstationPro虚拟机与主机远程连接

目录 一 &#xff0c;虚拟机与主机远程连接环境设置 二 虚拟机与主机远程连接 一 &#xff0c;虚拟机与主机远程连接环境设置 1 点击设置打开系统选项 2 打开远程控制 3 点击设置打开更新和安全 4 关闭病毒防护和防火墙 &#xff08;注&#xff1a;主机与虚拟机都要执行…

ubutu虚拟机和主机共享同一网络

ubutu虚拟机和主机共享同一网络 前言一、使用场景二、vmware设置三、主机windows设置四、虚拟机ubuntu配置 前言 ​ 本文采用的是共享同一网卡的方式达到虚拟机使用和主机一样的网络的目的。主要参考了虚拟机共享主机网卡连接的第一部分内容&#xff0c;感兴趣的朋友可以去大佬…

虚拟机三种网络连接方式

第一种连接方式-桥接模式 原理图&#xff1a; 桥接模式效果&#xff1a;通过桥接&#xff0c;我们让vm虚拟机和真正主机pc3处在了一片局域网下&#xff0c;vm虚拟机可以访问pc123也可以外网&#xff08;Internet)&#xff0c;同时pc123也可以访问vm虚拟机。好处是vm虚拟机可以…

VMware 虚拟机与主机网络互通

VMware连接网络 一、虚拟机服务开启二、本地网络虚拟机的网卡启动三、设置虚拟机四、IPv4设置 一、虚拟机服务开启 1.右击“此电脑”图标&#xff0c;单击“管理”&#xff0c;出现以下界面。 查看VMware是否开启&#xff0c;没有开启的话&#xff0c;就右击→“启动”。 二…