JWT令牌技术
文章目录
- 什么是令牌技术
- 为什么需要令牌技术呢
- JWT 令牌
- JWT 组成
- JWT 令牌的使用
- 1. 引入 JWT 依赖
- 生成 JWT 令牌
- 解析 JWT 令牌
什么是令牌技术
令牌技术是一种重要的安全技术,它在多个领域中发挥着关键作用。简单来说,令牌(Token)可以被视为系统的临时密钥,相当于账户名和密码,用于决定是否允许特定的请求,并判断该请求来自哪个用户。
在网络安全领域,令牌技术被广泛应用。它允许用户在不提供密码或其他凭证的前提下,访问网络和系统资源。这些令牌在系统中持续存在,直到系统重新启动。令牌的一个显著特点是其随机性和不可预测性,这使得黑客或恶意软件很难猜测出令牌的内容。
在支付领域,令牌技术则表现为一种虚拟账号技术。它将用户持有的信用卡或借记卡的16位主账号转化为一个与之对应的虚拟账号,并与具体的设备(如智能手机)绑定。如果发生黑客入侵事件,用户的真实卡号已经被令牌技术转化为虚拟账号,即使黑客获取了这个电子令牌,也无法直接利用。此外,如果用户的设备丢失,金融机构可以简单地使该设备上的电子令牌失效,从而保护用户的账户安全。
以苹果支付为例,它正是应用了令牌技术。这种技术不仅提高了支付的安全性,还大大节约了成本,因为金融机构无需在每次安全风险事件发生后都发放新的实体卡。
此外,OTP(一次性密码)令牌也是一种令牌技术的体现。它采用一种算法,每隔一段时间(如60秒)生成一个不可预测的随机数字组合,作为一次性的登录密码。这种技术增强了账号的安全性,因为它避免了定期更换密码的繁琐,同时也减少了密码被猜测或破解的风险。
简单点来说:令牌技术就是一个用户身份的标识,名称起的很高大上,其实本质上就是一个字符串。
为什么需要令牌技术呢
给大家举个例子,对于一个用户量很大的软件来说,它的服务器的数量肯定不止一个,因为如果只有一个服务器的话,对于多个客户端发来的请求,一个服务器短时间内是无法及时处理这些请求的话,如果在短时间内客户端的请求数量达到了服务器能处理的最大数量的请求的话,那么这个服务器就可能会发生宕机的问题,那么所有客户端的请求就无法得到处理,出现这样的问题就会造成很大的损失。
所以为了避免出现单个服务器出现宕机的问题,一个应用的背后会有多个服务器,并且通过负载均衡的做法来将不同数量的请求分配给指定的服务器,如果一个服务器当时可以接收的请求量较大的话,通过负载均衡的做法该服务器就可以得到较多数量的在承受范围之内的请求数量,对应的,对于那些当时可以接收的请求数量较少的服务器来说,通过负载均衡的操作该服务器得到的请求的数量就较少,这样就极大的降低了服务器出现宕机的问题。

但是通过负载均衡的做法的话,又会出现其他的问题,对于网站上用户的操作,往往需要先对用户的登录状态进行判断,对于一些操作只有用户登录之后才可以进行,而通常的判断用户是否登陆的的方法就是通过是否存在 Session 会话来判断,当用户成功登录之后呢,就创建出类似哈希表的结构将 Session 存储在服务器本地,然后通过响应将 SessionId 返回给客户端,并且存储在 Cookie 中,下一次客户端发送请求之后,就会将这个 SessionId 发送给服务器,服务器拿到请求的数据包之后,就可以根据这个 SessionId 来判断用户是否登录了。但是既然 Session 会话是存储在服务器本地,那么当有多个服务器的时候,如果用户前两分钟发送的登录请求是在服务器 A 中处理的话,那么当前会话就是在服务器 A 的本地存储的,那么如果过了两分钟之后用户又发送了其他操作请求的话,这时因为负载均衡的操作,该请求被分配到服务器 B 中去处理的话,服务器 B 就会先判断用户是否登录,根据客户端发来的请求中的 SessionId 来获取会话,但是因为服务器 B 中没有存储对应的会话,所以就会强制用户进行登录,这时用户就会问了:我不是刚刚登录了吗?为什么又让我登录呢?这是哪个xx写的程序。这样就会极大的影响用户的使用体验。
所以为了解决这个问题就出现了令牌技术,令牌技术会将令牌存储在客户端的浏览器上,而不是服务器上,当客户端发送请求的时候,将这个令牌也发送给服务器,服务器得到这个令牌之后就会对这个令牌进行解析,如果解析成功就可以认定该用户处于登录状态,反之则强制用户进行登录。
给大家举个例子:在之前网络还不发达的时候,如果我们需要住酒店的时候,我们进去酒店的时候需要将身份证交给负责人员,但是当我们进行其他也需要身份证的操作的时候,因为我们的身份证在酒店负责人那里,所以我们就需要先去酒店负责人那里拿身份证然后才能继续,但是现在,我们的身份信息都被录入了公安系统,我们需要住酒店,只需要刷身份证之后,身份证就会归还给我们了,那么我们就可以去干其他的事了,这也就是能证明自己身份的信息在用户手中的好处。
JWT 令牌
实现令牌技术的方法有很多种,今天我为大家分享的令牌技术是 JWT 令牌技术(Json Web Token),JWT官网
JWT 组成
JWT 由三个部分组成,每部分中间使用点 . 分隔:
- Header(头部):头部包括令牌的类型(既JWT)及使用的哈希算法
- Payload(负载):负载部分是存放有效信息的方法,里面是一些自定义的内容。此部分不建议存放敏感信息,因为此部分可以解码还原原始内容
- Signature(签名):此部分用于防止JWT内容被篡改,确保安全性
注意了签名是为了防止被篡改,而不是为了防止被解析,JWT之所以安全就是因为最后的签名。JWT令牌当前任何一个字符被篡改,整个令牌都会校验失败,就好比我们的身份证,它的目的不是为了不让别人知道,而是保证了我们的身份信息不会被篡改,人们很容易看到我们身份证上的信息,JWT也是。

当我们修改 Token 之后,再对其进行解析的时候,就会发现:该 Token 无法解析:

JWT 令牌的使用
1. 引入 JWT 依赖
首先因为 JWT 令牌属于第三方库,所以需要先引入 JWT 依赖:
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred --><version>0.11.5</version><scope>runtime</scope>
</dependency>
生成 JWT 令牌
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@SpringBootTest
public class JwtUtilTest {//设置令牌的过期时间为30分钟private static final long expiration = 1000 * 60 * 30;//密钥private static final String secretString = "fahfjkshfshdjfhskhfksjdhfjsdjfhsjkdfhs";//生成安全密钥private static final SecretKey KEY = Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretString));@Testpublic static void genJwt() {//自定义信息Map<String, Object> claim = new HashMap<>();claim.put("id",1);claim.put("username","zhangsan");String jwt = Jwts.builder().setClaims(claim) //自定义内容(负载).setIssuedAt(new Date()) //设置签证时间.setExpiration(new Date(System.currentTimeMillis() + expiration)) //设置过期时间.signWith(KEY) //签名算法.compact();System.out.println(jwt);}public static void main(String[] args) {JwtUtilTest.genJwt();}
}
当我们运行这个方法之后,就会报下面这个错误,原因是,我们的密钥的长度太短了,并且 idea 建议我们使用 io.jsonwebtoken.security.Keys#secretKeyFor(SignatureAlgorithm)方法来生成一个密钥:
java.lang.ExceptionInInitializerError
Caused by: io.jsonwebtoken.security.WeakKeyException: The specified key byte array is 224 bits which is not secure enough for any JWT HMAC-SHA algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a size >= 256 bits (the key size must be greater than or equal to the hash output size). Consider using the io.jsonwebtoken.security.Keys#secretKeyFor(SignatureAlgorithm) method to create a key guaranteed to be secure enough for your preferred HMAC-SHA algorithm. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.at io.jsonwebtoken.security.Keys.hmacShaKeyFor(Keys.java:96)at JwtUtilTest.<clinit>(JwtUtilTest.java:19)
Exception in thread "main"
所以我们就先使用 idea 建议的方法来生成一个密钥:
public static void genKey() {Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);String secretString = Encoders.BASE64.encode(key.getEncoded());System.out.println(secretString);
}
HS256 代指对应的编码方式:

我们运行这个方法获得一个符合规范的密钥:

private static final String secretString = "ZzvPBGOUCmilHmOl6jNmAbusvQryFipKn4VA1yrP7e0=";
base64编码之后的字符串应该只包含 A-Z, a-z, 0-9, ‘-’ 和 ‘_’ 这些字符。
根据生成的密钥生成 Token:

eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6aGFuZ3NhbiIsImlhdCI6MTcxMDA3NjI0OSwiZXhwIjoxNzEwMDc4MDQ5fQ.PzZoPdXaL2Guc3IZDt2m_-bmaIwu9GzgivTwus36Qno
解析 JWT 令牌
当我们使用相应的 API 生成 JWT 之后,客户端浏览器将服务器生成的令牌保存在浏览器中,下次发送请求的时候就将令牌传给服务器,服务器得到之后就需要对这个令牌进行解析。
我们将前面生成的 JWT 放在 JWT 解码网站上进行解析之后就可以得到我们的载荷部分,exp表示过期时间:

但是可以看到密钥部分是无法解析出来的,别人拿不到对应的密钥就无法伪造出 Token。
然后我们看看如何对 Token 进行解析:
public static void parseJwt() {String token = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6aGFuZ3NhbiIsImlhdCI6MTcxMDA3OTExMSwiZXhwIjoxNzEwMDgwOTExfQ.0_hCtlyhAPoQYnbyCvcKGDGS78YS6jxjNfrFtJ--E9M";Claims claims = Jwts.parserBuilder().setSigningKey(secretString).build().parseClaimsJws(token).getBody();System.out.println(claims);
}

令牌解析之后我们就可以看到里面的内容,如果在解析过程中没有出现报错,就说明解析成功了。
解析失败则会出现下面的报错:

通过 JWT 令牌技术就可以实现我们生活中的登录功能了。

相关文章:
JWT令牌技术
文章目录 什么是令牌技术为什么需要令牌技术呢JWT 令牌JWT 组成JWT 令牌的使用1. 引入 JWT 依赖生成 JWT 令牌解析 JWT 令牌 什么是令牌技术 令牌技术是一种重要的安全技术,它在多个领域中发挥着关键作用。简单来说,令牌(Token)可…...
从零学习Linux操作系统 第三十二部分 ansible中剧本的应用
一、什么是playbook及playbook的组成 1.Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 play就是一个个模块用列表的方式体现出来 playbook的语法是用YAML的预防进行书写的 2.YAML 简介 是一种表达资料序列的格式,类似XM…...
目标网站屏蔽右键检查(使用开发者工具)
问题: 通过网络触手中想要获取某网站的数据出现:鼠标右击,或按ctrl F10 键 无反应(也就是打不开类似谷歌的开发工具) 问题同等与: 解决网页屏蔽F12或右键打开审查元素 引用: 作者ÿ…...
docker安装ES、LogStash、Kibana
文章目录 一、安装Elasticsearch1. 安装Elasticsearch2. 安装IK分词器3. elasticsearch-head 监控的插件4. 配置跨域 二、安装LogStash三、安装kibana四、SpringBoot集成LogStash,将日志输出到ES中五、 启动项目,监控项目运行 提示:以下是本篇…...
解决对接淘宝开放平台添加商品图片问题
问题 之前工作因队友离开,只一天接手其部分且第二天就要上线此工具产品,测试提了一些Bug,在Bug中有一个是添加商品图片。前端告知不能用、电话离职队友说能用。没办法自己上、追踪代码。 en这块代码跟需求好像不太相符,重写。 …...
总结:Spring创建Bean循环依赖问题与@Lazy注解使用详解
总结:Spring创建Bean循环依赖问题与Lazy注解使用详解 一前提知识储备:1.Spring Bean生命周期机制(IOC)2.Spring依赖注入机制(DI)(1)Autowired注解标注属性set方法注入(2&…...
Mac下java环境搭建
JDK 教程:MAC安装JDK及环境变量配置-CSDN博客 建议JDK7和JDK8都装上,因为一些老项目是用JDK7开发,使用JDK8编译时报错。(若没有老项目,直接安装jdk8) 若配置环境变量时找不到JDK的安装路径,有两种方式: 方式一、mac默认位置为:/Library/Java/JavaVirtualMachines/…...
mac设置java环境变量
在 macOS 系统上,设置 JAVA_HOME 环境变量可以通过以下步骤进行: 打开终端应用程序。 输入以下命令来查找 Java 的安装路径:/usr/libexec/java_home 终端会返回 Java 的安装路径,类似 /Library/Java/JavaVirtualMachines/jdk1.…...
【笔记】Android 漫游定制SPN定制有关字段
一、SPN模块简介 【笔记】SPN和PLMN 运营商网络名称显示 Android U 配置 WiFiCalling 场景下PLMN/SPN 显示的代码逻辑介绍 【笔记】Android Telephony 漫游SPN显示定制(Roaming Alpha Tag) 二、相关配置字段 non_roaming_operator_string_array 是否…...
【MATLAB第99期】#源码分享 | 基于MATLAB的SHEPard模型多输入单输出回归预测模型
【MATLAB第99期】#源码分享 | 基于MATLAB的SHEPard模型多输入单输出回归预测模型 Shepard模型(简称SP模型)就是一种直观的、可操作的相似预测法,常用于插值。相似预测法基本原理按照相似原因产生相似结果的原则,从历史样本中集中找出与现在的最相似的一…...
python工具方法 47 基于paddleseg将目标检测数据升级为语义分割数据
在进行项目研究时,通常需要搜集开源数据集。但是所能搜集到的数据集通常会存在形式上的差异,比如我想要的是语义分割数据,而搜集到的数据集却是目标检测数据;在这种情况下所搜集的数据就完成没有利用价值了么?不,其还存在价值,我们可以通过模型训练对数据标签的标注粒度…...
OpenJudge - 38:计算多项式的导函数
总时间限制: 1000ms 内存限制: 65536kB 描述 计算多项式的导函数是一件非常容易的任务。给定一个函数f(x),我们用f(x)来表示其导函数。我们用x^n来表示x的n次幂。为了计算多项式的导函数,你必须知道三条规则: (1)、(C) 0 如果C是常量 (2)、…...
数据结构:顺序表(C++实现)
1 头文件 SeqList.h //SeqList.h #pragma once #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cassert> using namespace std; class SeqList { public://初始化SeqList();//销毁~SeqList();//头插void PushFront(int data);//头删void PopFront(…...
从零开始 TensorRT(7)C++ 篇:解析 ONNX
前言 学习资料: B站视频配套代码 cookbook 示例 参考源码:cookbook → 04-BuildEngineByONNXParser → pyTorch-ONNX-TensorRT 源码 C 代码量较多,已上传 GitHub OpenCV 安装: apt install libopencv-dev(1&…...
k8s集群的CA证书过期处理
文章目录 制作延期的CA证书获取CA全名准备签发申请配置生成新CA验证并替换CA 更新master组件的CA配置kube-apiserverkube-controller-managerkube-schedulerkube-admin检查证书过期时间 更新ServiceAccount secret更新node组件配置的CA更新kubelet连接配置签发kubelet自动申请的…...
linuxOPS基础_linux系统注意事项
Linux严格区分大小写 Linux 和Windows不同,Linux严格区分大小写的,包括文件名和目录名、命令、命令选项、配置文件设置选项等。 例如,Win7 系统桌面上有文件夹叫做Test,当我们在桌面上再新建一个名为 test 的文件夹时,…...
《探索虚拟与现实的边界:VR与AR谁更能引领未来?》
引言 在当今数字时代,虚拟现实(VR)和增强现实(AR)技术正以惊人的速度发展,并逐渐渗透到我们的日常生活中。它们正在重新定义人与技术、人与环境之间的关系,同时也为各行各业带来了全新的可能性。然而,究竟是VR还是AR更有潜力改变未来?本文将围绕这一问题展开深入探讨。…...
C++ 获取上一级文件夹路径
我们可能会经常遇到文件所在文件夹路径的问题,虽然各大平台也有提供方便快捷的API来实现,但是如果脱离平台本身,或者想实现跨平台的话,可以考虑用纯C的代码来实现这一需求 示例代码 #include <string> #include <ios…...
Apache Pulsar的分布式集群模式构建
1. 准备环境 6台带jdk8的Linux服务器(CentOS7为例) ip分别为: 主机名IP地址zookeeper1192.168.8.101zookeeper2192.168.8.102zookeeper3192.168.8.103pulsar1192.168.8.108pulsar2192.168.8.109pulsar3192.168.8.110 2. 下载Pulsar最新安…...
第三百八十六回
文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了Snackbar Widget相关的内容,本章回中将介绍TimePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的TimePickerDialog是一种弹出窗口,只不过窗口的内容固定显示…...
普通人用基础C语言从零搭建NES模拟器,背后藏着这些局限
一、普通人觉得遥不可及,他用基础C语言做到了好多人一提到NES模拟器,首先就会觉得那是只有专业大佬才做得来的,不是依靠现成框架去拼接,就是凭借复杂技术去累计,普通人想要从零基础开始上手,根本就是不可能…...
python学习-07字典
1字典的基本概念字典{ }是Python中唯一映射性数据结构(由关键字和值组成):1. 字典定义:{key1:value, key2:value},key在字典中是唯一的;2. 字典是一种可变的容器模型,可以存储任意类型对象(元素可以是字典、列表、字符…...
从零到CV算法工程师:25篇文章带你突破面试关
从零到CV算法工程师:25篇文章带你突破面试关一直有同学问我面试的事儿,我没急着写。因为面试这东西,说太细容易引发焦虑,而且每个人情况不同。 不过有些经验是通用的,今天分享给大家。 老板想招什么样的人 假如我是面试…...
Chrome扩展开发实战:利用manifest.json与service-worker实现侧边栏动态控制
1. 从零开始理解Chrome扩展侧边栏 第一次接触Chrome扩展开发时,我被manifest.json里密密麻麻的配置项搞得头晕眼花。直到做了几个实际项目才发现,其实掌握几个关键参数就能实现强大的功能。今天我们就来聊聊如何用manifest.json和service-worker这对黄金…...
微信小程序的校园快递代领学生跑腿平台小程序
目录同行可拿货,招校园代理 ,本人源头供货商功能模块划分技术实现要点扩展功能项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块划分 用户端功能 注册与登录:支持手…...
微信小程序的校园快递代取系统
目录同行可拿货,招校园代理 ,本人源头供货商微信小程序校园快递代取系统功能分析用户端功能配送员端功能后台管理功能扩展功能项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 微信小程序…...
基于Grafana+Prometheus+Micrometer的JVM性能监控实战指南
1. 为什么需要JVM性能监控系统? 第一次线上服务崩溃的经历让我记忆犹新。那天凌晨三点,报警电话把我从睡梦中惊醒,线上订单服务完全瘫痪。排查了半天才发现是JVM老年代内存泄漏导致Full GC频繁触发,最终拖垮了整个系统。如果当时有…...
Web前端事件循环:从浏览器进程模型到异步任务调度实战
1. 浏览器进程模型:理解前端运行的底层环境 浏览器远比我们想象的要复杂得多。每次打开一个网页,背后其实运行着一整套精密的进程和线程协作系统。想象一下,这就像一家餐厅的运作:浏览器进程是前台接待,负责接待顾客&a…...
STM32F1xx HAL库 + FreeRTOS实战:构建带日志输出的交互式Shell终端
1. 为什么需要交互式Shell终端 在嵌入式开发中,调试手段往往决定了开发效率。想象一下,当你的设备在实验室运行良好,到了现场却出现偶发性故障,传统的LED灯调试方式就像在黑夜里用手电筒找钥匙 - 效率低下且信息有限。而基于STM32…...
这是我的第一篇文章
以后将会发布一些有关我Java的学习过程...
