3.JJWT

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

目录

1.JWT简介
2.JWT的结构
3.基于服务器的传统身份认证
4.基于token的身份认证
5. JWT的优势
6.Java中使用JJWT实现JWT

1.JWT简介

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

2.JWT的结构

在这里插入图片描述
JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:头部(header)载荷(payload)(类似于货车的载荷就是货物)和签证(signature)。因此,一个典型的JWT看起来是这个样子的:aaaaa.bbbbbb.cccccc。对于每一部分:

header:

JWT的第一部分是header,它包含两部分信息:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。如:

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

然后,用Base64加密(该加密是可以对称解密的)对这个JSON进行编码就得到了JWT的第一部分。

payload:

JWT的第二部分是payload,它包含声明信息。声明是关于实体(通常是用户)和其他数据的声明。声明有三种类型:registered, public 和 private。

  1. Registered claims : 注册声明有一组预定义的声明,它们不是强制的,但是推荐:
    1.1 iss (issuer):jwt签发者;
    1.2 sub (subject):jwt所面向的用户;
    1.3 aud (audience):接收jwt的一方;
    1.4 iat (issued at time): jwt的签发时间;
    1.5 exp (expiration time):jwt的过期时间,这个过期时间必须要大于签发时间;
    1.6 nbf (not before):定义在什么时间之前,该jwt都是不可用的;
    1.7 jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
  2. Public claims : 可以随意定义。
  3. Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。

对payload进行Base64编码就得到JWT的第二部分。注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。payload示例:

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

signature:

JWT的第三部分是一个签证信息,这个签证信息由三部分组成:Base64编码后的headerBase64编码后的payload和一个自定义的私人密钥secret

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

这个signature部分需要base64加密后的header和payload通过使用.连接组成的字符串,和通过header中声明的加密方式进行加盐secret组合加密,构成了jwt的第三部分。
 
签名主要是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

注意:JWT的签发生成也是在服务器端的,secret的作用是进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。 对于上述的总结,这是JWT官网的一张图:
在这里插入图片描述

3.基于服务器的传统身份认证

由于HTTP协议是无状态的,这就意味着如果我们已经通过账号密码进行认证后,在下一次请求的时候,服务器仍然不知道该请求是有谁发起的,就必须还得认证。

所以为了解决该问题,传统的方式是将已经认证过的用户信息存储在服务器上,也就是存储在Session对象中,并将这个Session的sessionId存储到Cookie中响应回浏览器。这样客户端就拿到了自己在服务器的认证信息,下次请求时就可以携带着这个sessionId,服务器就能知道该用户是已经认证过了的了。这就是传统的基于Session的认证、会话保持技术。

但是这种基于服务器的身份认证方式存在一些问题:

  1. 服务器负担增加:每次用户认证通过以后,服务器需要消耗内存来保存用户信息,随着认证通过的用户越来越多,服务器的在这里的开销和压力就会越来越大。
  2. 扩展局限 : 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。
  3. CSRF : 因为是基于Cookie来进行用户识别的,Cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

4.基于token的身份认证

由于上述Session+Cookie搭配存在的问题,所以后续提出了基于token的鉴权机制,token类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要再去考虑用户是在哪一台服务器登录了,这就为应用的扩展提供了便利,如同时服务器同时服务于PC浏览器和移动端App。

基于token的认证流程:

1.客户端带着用户名和密码请求服务器;
2.服务器对用户身份进行认证,通过认证后生成一个包含用户信息的token,作为用户的唯一凭证并返回给客户端;
3.客户端存储token,并在每次请求时在请求头header中携带上这个token值;
4.服务器验证token值,通过则完成请求。
 
注意:有时服务器需要设置为接受来自所有域的请求,用 Access-Control-Allow-Origin: *

通常情况下,token放在Authorization header中,并用Bearer schema。header应该看起来是这样的:Authorization: Bearer <token>

服务器上的受保护的路由将会检查Authorization header中的JWT是否有效,如果有效,则用户可以访问受保护的资源。如果JWT包含足够多的必需的数据,那么就可以减少对某些操作的数据库查询的需要,尽管可能并不总是如此。
 
如果token是在授权头(Authorization header)中发送的,那么跨源资源共享(CORS)将不会成为问题,因为它不使用Cookie。

5. JWT的优势

  1. 无状态和可扩展性:Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。
  2. 安全性:Token不是Cookie。(The token, not a cookie.)每次请求的时候Token都会被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话!还有一点是,token在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。还有一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。
  3. 基于标准化:因为JSON的通用性,多种语言和多家公司采用标准化的 JSON Web Token (JWT)已经存在多个JWT的工具库。
  4. 便于传输:JWT的构成非常简单,字节占用很小,所以它是非常便于传输的。
  5. 更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可。
  6. 去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
  7. 更适用于移动应用:当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。

6.Java中使用JJWT实现JWT

Java中提供了JJWT库来实现对JWT的快速生成和便捷解析,首先导入依赖:

<!--        jjwt-->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>

创建JWT工具类JwtUtils.java

public class JwtUtils {/*** 签名需要的私有密钥*/private static final String SECRET = "myScrect";/*** 重载createJwt,通过用户信息和生成Jwt* @param user 用户信息* @return token*/public static String createJwt(User user) {return createJwt(user,-1);}/*** 通过用户信息和过期时间生成Jwt* @param user 用户信息* @param ttlMillis 过期时间* @return token*/public static String createJwt(User user, long ttlMillis) {// 签名算法 HS256,即jjwt已经封装header中需要的算法名称SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成Jwt的时间,即签发时间long nowMillis = System.currentTimeMillis();//构建JwtJwtBuilder builder = Jwts.builder()//jwt的唯一标识.setId(String.valueOf(user.getId()))//jwt面向用户.setSubject(user.getTelephone())//jwt的签发者.setIssuer("Korbin")//jwt的签发时间.setIssuedAt(new Date(nowMillis))//设置签名使用的签名算法和签名使用的秘钥.signWith(signatureAlgorithm,SECRET);//自定义payload的claim信息builder.claim("role", "admin");// 设置过期时间,需要大于签发时间if (ttlMillis >= 0) {long expMillis = nowMillis + ttlMillis;builder.setExpiration(new Date(expMillis));}String token = builder.compact();return token;}/*** 解析jwt,解析时若过期会抛出ExpiredJwtException异常* @param jwt token* @return jwt对象*/public static Claims parseJwt(String jwt){//解析jwtJwtParser parser = Jwts.parser();//获取解析后的对象Claims claims = Jwts.parser()//设置签名秘钥,和生成的签名的秘钥一模一样.setSigningKey(SECRET)//设置需要解析的jwt.parseClaimsJws(jwt).getBody();return claims;}}

测试运行:

public static void main(String[] args) {User user = new User();user.setId(10007L);user.setTelephone("13511448855");String token = JwtUtils.createJwt(user,1000*60);System.out.println(token);Claims claims = JwtUtils.parseJwt(token);System.out.println("jwtId:"+claims.getId());System.out.println("jwtSubject:"+claims.getSubject());System.out.println("jwtIssuer:"+claims.getIssuer());System.out.println("jwtIssuedAt:"+claims.getIssuedAt());System.out.println("role:"+claims.get("role"));System.out.println("expiration:"+claims.getExpiration());}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/3yIq6vtl.shtml

相关文章

JWT技术

JWT 一、 JWT 实现无状态 Web 服务 1、什么是有状态 有状态服务&#xff0c;即服务端需要记录每次会话的客户端信息&#xff0c;从而识别客户端身份&#xff0c;根据用户身份进行请求的处理&#xff0c;典型的设计如tomcat中的session。 例如登录&#xff1a;用户登录后&am…

token学习笔记(JWT、jjwt的使用及案例实现)

文章目录 1. 首先、了解什么是会话2. 会话跟踪的主要技术3. Token 令牌学习3.1 流程图3.2 token3.3 JWT(JSON web Tokens)Json web 令牌(规范)3.4 JWT结构3.5 JWT需要的依赖3.6 JWT的获取与验证流程3.7JWT的使用方式3.8 jjwt的使用&#xff08;创建JWT方式&#xff09;1. jjwt需…

JWT 进阶 -- JJWT

###jwt是什么? JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成&#xff0c;其中名称为字符串&#xff0c;值为任意JSON值。JWT有助于在clear(例如在URL中)发送这样的信息&#xff0c;可以被信任为不可读(即加密的)、不可修改的(即签名)和URL - safe(即Base64编码…

JWT详解和使用(jjwt)

JWT详解和使用 JWT是啥 JWT&#xff08;JSON Web Token&#xff09;是一个开放标准(RFC 7519)&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任&#xff0c;因为它是数字签名的。 下列场景中使用…

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;使用了手动设置虚拟…