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

article/2025/11/9 15:58:47

文章目录

    • 1. 首先、了解什么是会话
    • 2. 会话跟踪的主要技术
    • 3. Token 令牌学习
        • 3.1 流程图
        • 3.2 token
        • 3.3 JWT(JSON web Tokens)Json web 令牌(规范)
        • 3.4 JWT结构
        • 3.5 JWT需要的依赖
        • 3.6 JWT的获取与验证流程
        • 3.7JWT的使用方式
        • 3.8 jjwt的使用(创建JWT方式)
          • 1. jjwt需要的依赖
          • 2.测试类
          • 3.RSA算法支持
            • 4.使用自己的key
      • 3.9 前端如何使用token,并且加入请求头

1. 首先、了解什么是会话

会话是指一个终端用户与交互系统进行通讯的过程

2. 会话跟踪的主要技术

2.1 URL重写技术
就是在URL结尾添加一个附加数据以标识该会话,会把会话ID通过URL的信息传递过去,以便在服务端进行识别不同的用户。

2.2 隐藏表单域
将会话ID添加到HTML表单元素中提交到服务器,此表单不再客户端显示。

2.3 cookie
Cookie是web服务器发送给客户端的一小段信息,客户端请求时可以读取该信息发送到服务器端,进而进行用户的识别。对于客户端的每次请求,服务器都会将KCookie发送到客户端,在客户端可以进行保存,以便下次使用。

2.4 session
在服务端会创建一个session对象,产生一个sessionID来标识这个session对象,然后将这个sessionID放入到Cookie中发送到客户端,下一次访问时,sessionID发送到服务器,在服务端进行识别不同的用户。

session是依赖Cookie的,如果Cookie被禁用,那么session也将失效,session默认的会话时长为30分钟。

2.5 Token
token是令牌,访问系统的凭证。
token是服务端生成的一串字符串,客户端首先会请求一个令牌,当第一次登录后,服务器会生成一个token并将此token返回给客户端后,以后客户端只需带上这个token请求数据即可,无需再次带上用户名和密码。

2.6 三者相同点与区别
相同点:都是用于身份验证或鉴权的,都是服务器产生的
区别:
1.cookie是保存在客户端,session是存储在服务器的
2.session保存在服务器的内存,默认是30分钟,token是保存在服务器的数据库里面,持久。

3. Token 令牌学习

3.1 流程图

在这里插入图片描述
① 客户端使用用户名和密码请求登录
② 服务端收到请求,验证用户名和密码
③ 验证成功后,服务端会签发一个token,再把这个token返回给客户端
④ 客户端收到token后可以把它存储起来,比如放到cookie中
⑤ 客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
⑥ 服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据

3.2 token

  1. token加密方式
    对称加密:DES,AES、
    双钥加密:RSA,一般用于金融项目里面做签名
    只加密不解密:MD5,SHA系列
    编码格式:Base64
    2.token有两种
    access_token:时效15分钟到2小时之间
    refresh_token:时效15天

3.3 JWT(JSON web Tokens)Json web 令牌(规范)

这种基于token的认证方式相比传统的session认证方式更节约服务器资源,并且对移动端和分布式更加友好。其优点如下:
① 支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题
② 无状态:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力
③ 更适用CDN:可以通过内容分发网络请求服务端的所有资料
④ 更适用于移动端:当客户端是非浏览器平台时,cookie是不被支持的,此时采用token认证方式会简单很多
⑤ 无需考虑CSRF:由于不再依赖cookie,所以采用token认证方式不会发生CSRF,所以也就无需考虑CSRF的防御

3.4 JWT结构

1.Header
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存
{
“alg”: “HS256”,
“typ”: “JWT”
}

2.Payload
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

这些预定义的字段并不要求强制使用。除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中,如下例:

{
“sub”: “1234567890”,
“name”: “Helen”,
“admin”: true
}
请注意,默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息

3.Signature
签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名
H M A C S H A 256 ( b a s e 64 U r l E n c o d e ( h e a d e r ) + " . " + b a s e 64 U r l E n c o d e ( p a y l o a d ) , s e c r e t ) HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)
HMACSHA256(base64UrlEncode(header)+“.”+base64UrlEncode(payload),secret)
在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用.分隔,就构成整个JWT对象

3.5 JWT需要的依赖

在这里插入图片描述

3.6 JWT的获取与验证流程

package edu.zhku.fire_ant_project;import org.apache.commons.codec.binary.Base64;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;@SpringBootTest
public class FireAntProjectApplicationTest {//创建header//@Testpublic String getHeader() throws UnsupportedEncodingException {String header="{\"arg\":\"HS256\",\"typ\":\"JWT\"}";//把header的Json转成Base64URL编码的字符串String header64=Base64.encodeBase64URLSafeString(header.getBytes("UTF-8"));System.out.println("header64="+header64);return header64;}//创建Payload// @Testpublic String getPayload() throws UnsupportedEncodingException {String payload="{\"sub\":\"username\",\"id\":\"1001\",\"role\":\"admin\"}";String payload64=Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"));System.out.println("play="+payload64);return payload64;}//创建签名Signature// @Testpublic void getSignature() throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {String secret = "h1d444wt65ywj454et45hdh08797hjh1";System.out.println(secret.length());//创建Mac类Mac mac=Mac.getInstance("HmacSHA256");//创建安全的密钥对象SecretKeySpec spec=new SecretKeySpec(secret.getBytes("UTF-8"),"HmacSHA256");//让Mac对象使用指定的密钥对象mac.init(spec);//准备数据String data=getHeader()+"."+getPayload();//生成签名值byte[] bytes=mac.doFinal(data.getBytes("UTF-8"));//把bytes转为StringString signMsg=Base64.encodeBase64URLSafeString(bytes);System.out.println("sign="+signMsg);//组成完整的jwtString jwt = data+"."+signMsg;System.out.println("jwt="+jwt);}//验证签名值@Testpublic void checkSign() throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {//密钥String secret="h1d444wt65ywj454et45hdh08797hjh1";//jwt数据String jwt="eyJhcmciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" +"." +"eyJzdWIiOiJ1c2VybmFtZSIsImlkIjoiMTAwMSIsInJvbGUiOiJhZG1pbiJ9" +"." +"vD3nhQz_gVlqV6FLfxW357Mi313bThc2ajyhVic1XNQ";//验证签名:使用和创建时一样的算法,再计算出一个签名值,和jwt比较String data =jwt.substring(0,jwt.lastIndexOf("."));//获取jwt中的签名String signature=jwt.substring(jwt.lastIndexOf(".")+1);
//        System.out.println("data="+data);
//        System.out.println("signature="+signature);//重新计算签名值Mac mac =Mac.getInstance("HmacSHA256");SecretKeySpec spec=new SecretKeySpec(secret.getBytes("UTF-8"),"HmacSHA256");mac.init(spec);byte[] bytes=mac.doFinal(data.getBytes("UTF-8"));String sign=Base64.encodeBase64URLSafeString(bytes);System.out.println("signature=sign:"+(signature.equals(sign)));}
}

3.7JWT的使用方式

  1. 首先用户登录校验后,服务器会返回jwt token
  2. 客户端获取jwt token,使用cookie或localStorage存储jwt token,但这样不能跨域,采用的方式放在请求header的Authorization中,也可以放在get或者post请求中
  3. 客户端访问其他api接口,传递token给服务器,服务器认证token后,返回给请求的数据。

Authorization:Bearer

3.8 jjwt的使用(创建JWT方式)

1. jjwt需要的依赖

在这里插入图片描述

2.测试类
 //jjwt的使用@Testpublic void test01(){//创建一个key使用HS256算法Key key= Keys.secretKeyFor(SignatureAlgorithm.HS256);//使用jjwt创建jwtString jws=Jwts.builder().setSubject("username").signWith(key).compact();System.out.println("jws:\n"+jws);jws="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJmaXJlX2FudF9wcm9qZWN0X2FkbWluIn0.ecJI1-6rOtyuPvK8ZxsxddE0nly1CQXxoNfWi9sIhdc";//验证JWT,key已刷新,则会抛出异常Claims body=Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jws).getBody();String subject=body.getSubject();System.out.println("subject:\n"+subject);}
3.RSA算法支持
   //RSA算法支持,私钥创建jwt,公钥验证jwt@Testpublic void test02(){KeyPair keyPair =Keys.keyPairFor(SignatureAlgorithm.RS256);PrivateKey aPrivate=keyPair.getPrivate();String jws=Jwts.builder().setSubject("username").signWith(aPrivate).compact();System.out.println("jws:\n"+jws);jws="eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJmaXJlX2FudF9wcm9qZWN0X2FkbWluIn0.JiCzArgVdQNGkpFLaxa0h11KGJsJrj";//验签,使用公钥try {String subject = Jwts.parserBuilder().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(jws).getBody().getSubject();System.out.println("subject:\n" + subject);}catch (SignatureException se){se.printStackTrace();System.out.println("false");}catch (Exception e){e.printStackTrace();}
4.使用自己的key
    //使用自己的key@Testpublic void privateKey(){String secret = UUID.randomUUID().toString().replaceAll("-","");//安全的密钥对象SecretKey secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));String token = Jwts.builder().setSubject("username").signWith(secretKey,SignatureAlgorithm.HS256).compact();System.out.println(secret.length());System.out.println(token);//验证JWT,key已刷新,则会抛出异常Claims body=Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token).getBody();String subject=body.getSubject();System.out.println("subject:\n"+subject);}

//规定token时间

**   public void privateKey(){Date date = new Date(System.currentTimeMillis() + 60000);
//        String secret = UUID.randomUUID().toString().replaceAll("-","");
//        //安全的密钥对象String secret ="dd9b84d01c0940c6a5723a744d0d66a8";SecretKey secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
//      String token = Jwts.builder().setSubject("fire_ant_project_admin")
//                .signWith(secretKey,SignatureAlgorithm.HS256)
//                .setExpiration(date)
//                .compact();String token ="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJmaXJlX2FudF9wcm9qZWN0X2FkbWluIiwiZXhwIjoxNjQyOTA5NTI0fQ.tHfJm-MsEaaqlakOFoRvWMog-weCeSGlJVlGV3YyVPs";System.out.println(token);//验证JWT,key已刷新,则会抛出异常Claims body=Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token).getBody();String subject=body.getSubject();System.out.println("subject:\n"+subject);}//**

3.9 前端如何使用token,并且加入请求头

1.可以通过cookie存储
document.cookie=token;
2.加入请求头Authoriziation
① headers:{“Authoriziation”:token}
② 存储:在这里插入图片描述获取:
在这里插入图片描述


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

相关文章

JWT 进阶 -- JJWT

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

JWT详解和使用(jjwt)

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

JJWT 实现JWT

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

什么是JWT?

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

JWT的学习和JJWT的使用

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

JWT详解

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

JWT详解、JJWT使用、token 令牌

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

Java的JJWT实现JWT

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

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

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

虚拟机VMware和宿主机连接

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

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

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

虚拟机与主机之间通信

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

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

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

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

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

vmware虚拟机与主机共享网络

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

Virtualbox虚拟机与主机相互访问

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

虚拟机和主机无法连接

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

虚拟机和主机的网络访问

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

VMwareWorkstationPro虚拟机与主机远程连接

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

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

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