当前位置: 首页 > news >正文

JWT入门,jwt可以解密吗?

JWT

什么是 JWT

JSON Web Token,通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全地传输信息

  • 官网:https://jwt.io/
  • SDK: https://jwt.io/libraries (含Java和各种语言)
  • Java SDK(上面的SDK链接得到): https://github.com/auth0/java-jwt (java sdk也有很多种,这是其中一种)
  • 可以根据自己的喜好选择 SDK,不同的SDK的API设计有差异,那自然会有好坏
  • 本项目种使用的 SDK 也是官方推荐的其中一种(选官方的比来路不明的好)

JWT 有什么用?

JWT 最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求之前,都要先进行 JWT 安全校验,通过之后再进行处理。

JWT 的组成

JWT 由 3 部分组成,用 . 拼接

格式是 Header.Payload.Signature

  • Header(头信息)
{'typ': 'JWT','alg': 'HS256'
}

包含类型typ和算法alg,类型写死 JWT,算法可以自己决定,这里用HS256举例

  • Payload
实际的有效数据,你要传的业务数据,例如:
  • Signature
Signature是这么算出来的?var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'your_secret');说明:
1、header和payload先用base64加密用点链接起来,再用header里alg所指定的算法计算摘要
2、your_secret 就是秘钥,加密方和解密方共同知道的,解密的时候要用

补充

当你拿到一段jwt字符串的时候(就是三段式的那串),你能知道什么?

对于 xxx.yyy.zzz,你可以知道

  • xxx,可以用base64解密xxx
  • yyy,本以为base64不能解密,结果可以,另外,我也遇到过不能解密的,可能是自己额外加密了
  • zzz,不能base64解密

注意:不要整段粘贴进去用base64解密,要分段,否则可能会出现解密不了的情况。

例子

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0ZWFjaGVyIjp7Im5hbWUiOiJNaXNzIExlZSJ9LCJzZXgiOnRydWUsIm5hbWUiOiJTdG9uZSIsImNvdXJzZUxpc3QiOlt7Im5hbWUiOiJNYXRoIiwiY3JlZGl0cyI6NH0seyJuYW1lIjoiRW5nbGlzaCIsImNyZWRpdHMiOjN9XSwiZXhwIjoxNjkxNDExMzcyLCJhZ2UiOjIwfQ.C2LJfyeeS2E0tpS12o-MnQWvn3B7ecK_ul3kudpiAPE注意一定要分段粘贴进去进行base64解密,不要一整个整体,本例子没有问题,有些别的例子会出现yyy部分不能解密的情况!!!base64解密第一段:{"typ":"JWT","alg":"HS256"}
base64解密第一段:{"teacher":{"name":"Miss Lee"},"sex":true,"name":"Stone","courseList":[{"name":"Math","credits":4},{"name":"English","credits":3}],"exp":1691411372,"age":20}
base64解密第一段:(乱码,看来是解密不了)

Java 例子

其实实际的使用过程,Java 作为后端仅仅需要写解析jwt的,对于封装,这是前端要干的事情。

package com.wyf.test.jwt;import io.jsonwebtoken.*;import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;public class JWTTest {private static final String MY_SECRET = "xAy23hz23YK";// 加解密用的秘钥public static void main(String[] args) throws InterruptedException {String jwtString = testGetJwtString();//Thread.sleep(4*1000);// 模拟超市的情况是否能检查出来System.out.println("\n-------------------\n");testParseJwtString(jwtString);}// 得到加密的字符串,这个一般来说不是Java写的,肯定是前端人员写的,JS(react/vue等)public static String testGetJwtString() {/*格式:Header.Payload.Signatureheader的格式是:{'typ': 'JWT','alg': 'HS256'}其中类型typ写死,alg可选,这里选HS256算法Payload 是实际的数据Signature的计算方式如下(参考如下用JS写的伪代码):var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);var signature = HMACSHA256(encodedString, 'your_secret');其中 your_secret 就是秘钥,加密方和解密方共同知道的,解密的时候要用*/// 设置 token 有效期long tokenLifespan = 3 * 1000; // 30 秒Date expireDateTime = new Date(System.currentTimeMillis() + tokenLifespan);// 用 Java 中引入的 JWT 包里的 APIJwtBuilder jwtBuilder = Jwts.builder();String jwtString = jwtBuilder// header.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")// payload (claim 其实就是payload的意思,就是你要传的数据).setClaims(prepareMapPayloadData())// 可选,设置 token 有效期.setExpiration(expireDateTime)// signature (解密的时候用的secret不对的话会抛出signature无法匹配的异常:io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature.).signWith(SignatureAlgorithm.HS256, MY_SECRET)// 用点连接起来.compact();System.out.println("jwtString:" + jwtString);System.out.println("token duration(Sec):" + (tokenLifespan / 1000));SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));System.out.println("expireDateTime:" + simpleDateFormat.format(expireDateTime));return jwtString;}// 我在想这个方法根本就不需要返回payload里的值,如果使用JWT,仅仅是validate一下signature是不是正确的、达到鉴权效果就可以了public static Object testParseJwtString(String jwtString) {JwtParser jwtParser = Jwts.parser();// 设置解密用的秘钥(解密的时候用的secret不对的话会抛出signature无法匹配的异常)jwtParser.setSigningKey(MY_SECRET);// parse 的时候就会校验签名,不正确的时候会从这行抛出异常,也会校验token是否超时!如果超时爆出// Exception in thread "main" io.jsonwebtoken.ExpiredJwtException: JWT expired at 2023-08-07T18:59:42Z. Current time: 2023-08-07T18:59:44Z, a difference of 2416 milliseconds.  Allowed clock skew: 0 milliseconds.Jwt parse = jwtParser.parse(jwtString);Header header = parse.getHeader();Object body = parse.getBody();// 其API是设计成用Object接收的System.out.println("header: " + (header != null ? header.getClass().toString() + ", " + header : "null"));System.out.println("body: " + (body != null ? body.getClass().toString() + ", " + body : "null"));return body;}/*** method to convert object to a map* @param obj* @return* @throws IllegalAccessException*/public static Map<String, Object> getObjectToMap(Object obj) throws IllegalAccessException {Map<String, Object> map = new HashMap<String, Object>();Class<?> cla = obj.getClass();Field[] fields = cla.getDeclaredFields();for (Field field : fields) {field.setAccessible(true);String keyName = field.getName();Object value = field.get(obj);if (value == null)value = "";map.put(keyName, value);}return map;}public static Map<String, Object> prepareMapPayloadData() {Map<String, Object> objectToMap;try {objectToMap = getObjectToMap(preparePayloadData());} catch (IllegalAccessException e) {throw new RuntimeException(e);}System.out.println("payload map: " + objectToMap);return objectToMap;}public static Student preparePayloadData() {List<Course> courseList = new ArrayList<Course>();Course course1 = new Course();course1.setName("Math");course1.setCredits(4);Course course2 = new Course();course2.setName("English");course2.setCredits(3);courseList.add(course1);courseList.add(course2);Teacher teacher = new Teacher();teacher.setName("Miss Lee");Student student = new Student();student.setName("Stone");student.setAge(20);student.setSex(true);student.setTeacher(teacher);student.setCourseList(courseList);return student;}public static class Student {private String name;private Integer age;private Boolean sex;private Teacher teacher;private List<Course> courseList;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Boolean getSex() {return sex;}public void setSex(Boolean sex) {this.sex = sex;}public Teacher getTeacher() {return teacher;}public void setTeacher(Teacher teacher) {this.teacher = teacher;}public List<Course> getCourseList() {return courseList;}public void setCourseList(List<Course> courseList) {this.courseList = courseList;}}public static class Teacher {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}public static class Course {private String name;private Integer credits;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getCredits() {return credits;}public void setCredits(Integer credits) {this.credits = credits;}}
}

相关文章:

JWT入门,jwt可以解密吗?

JWT 什么是 JWT JSON Web Token&#xff0c;通过数字签名的方式&#xff0c;以 JSON 对象为载体&#xff0c;在不同的服务终端之间安全地传输信息 官网&#xff1a;https://jwt.io/SDK: https://jwt.io/libraries (含Java和各种语言)Java SDK(上面的SDK链接得到): https://g…...

36.利用解fgoalattain 有约束多元变量多目标规划问题求解(matlab程序)

1.简述 多目标规划的一种求解方法是加权系数法&#xff0c;即为每一个目标赋值一个权系数&#xff0c;把多目标模型转化为一个单目标模型。MATLAB的fgoalattain()函数可以用于求解多目标规划。 基本语法 fgoalattain()函数的用法&#xff1a; x fgoalattain(fun,x0,goal,weig…...

EPPlus 读取和生成Excel

在项目中添加了EPPlus库的引用&#xff0c;你可以通过NuGet包管理器或手动将EPPlus库添加到项目中。同时&#xff0c;需要注意的是EPPlus库支持的是xlsx格式的Excel文件。 读取 使用EPPlus读取本地Excel文件的示例代码如下&#xff1a; using OfficeOpenXml;public void Rea…...

Java wait() notify() join()用法讲解

一、wait() 1. 源码&#xff1a; 实际调用本地方法 2. 作用 释放当前锁&#xff0c;并让当前线程进入等待状态&#xff1b;timeoutMillis为等待时间&#xff0c;单位毫秒&#xff0c;如果为0则表示无限等待下去&#xff1b;该方法使用前提是&#xff1a;当前执行线程必须持…...

新手注意事项-visual studio 来实现别踩白块儿

自己之前为了熟悉easyx练习过一个简单的项目&#xff0c;别踩白块儿&#xff0c;链接在这里&#xff0c;别踩白块儿&#xff0c;当时比较稚嫩&#xff0c;很多东西都不会&#xff0c;可以说是只知道最基本的语法&#xff0c;头文件都不知道&#xff0c;一个一个查资料弄懂的&am…...

【力扣】2810. 故障键盘 <模拟>

【力扣】2810. 故障键盘 你的笔记本键盘存在故障&#xff0c;每当你在上面输入字符 ‘i’ 时&#xff0c;它会反转你所写的字符串。而输入其他字符则可以正常工作。给你一个下标从 0 开始的字符串 s &#xff0c;请你用故障键盘依次输入每个字符。返回最终笔记本屏幕上输出的字…...

Docker desktop使用配置

1. 下载安装 https://www.docker.com/ 官网下载并安装doker desktop 2. 配置镜像 &#xff08;1&#xff09;首先去阿里云网站上进行注册&#xff1a;https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors &#xff08;2&#xff09;注册完成后搜索&#xff1a;容…...

第一百二十一天学习记录:线性代数:矩阵乘法运算(宋浩板书)

在编程和学习数据结构的过程中&#xff0c;发现有些算法会用到矩阵和矩阵的乘法运算&#xff0c;因此先将这一个知识点学习一下。 矩阵和行列式的区别 各种矩阵的概念 矩阵运算 乘法☆ 总结三条不满足...

模拟实现消息队列项目(系列3) -- 服务器模块(硬盘管理)

目录 前言 1. 创建项目 2. 创建核心类 2.1 Exchange 2.2 MSQueue 2.3 Binding 2.4 Message 3. 数据库设计 3.1 SQLite 配置 3.2 Mapper层代码实现 3.2.1 创建表操作 3.2.2 交换机 队列 绑定的增加和删除 3.3 实现DataBaseManager 3.4 DataBaseManager单元测试 4.…...

【iOS】锁

线程安全 当一个线程访问数据的时候&#xff0c;其他的线程不能对其进行访问&#xff0c;直到该线程访问完毕。简单来讲就是在同一时刻&#xff0c;对同一个数据操作的线程只有一个。而线程不安全&#xff0c;则是在同一时刻可以有多个线程对该数据进行访问&#xff0c;从而得…...

杰发科技(合肥)2021笔试题

笔试时间:2020.10.17 ,10:30-12:00。 岗位:Linux 驱动工程师。 题型:选择题8道,填空题10道,编程题4道。 杰发科技主要做汽车电子,由北京四维图新控股,对汽车电子感兴趣的有机会可以应聘试试。 选择题 1、128,4 #include<stdio.h> unsigned int getstrsiz…...

Java堆排序

目录 PriorityQueue自己实现 PriorityQueue public class PriorityQueueMain {public static void main(String[] args) {int[] temp {40, 2, 33, 26, 35, 8, 8, 26, 29, 2};PriorityQueue<Integer> priorityQueue new PriorityQueue<>();for (int i 0; i <…...

GitHub的基本使用教程

GitHub是一个基于web的版本控制和协作平台。它允许开发人员将他们的代码存储库存储在云中&#xff0c;并与其他人一起进行工作。GitHub还提供了各种工具和功能来帮助开发人员管理和组织他们的代码项目&#xff0c;包括拉出请求、问题跟踪、代码评论等等。此外&#xff0c;它托管…...

objectMapper.configure 方法的作用和使用

objectMapper.configure 方法是 Jackson 提供的一个用于配置 ObjectMapper 对象的方法。ObjectMapper 是 Jackson 库的核心类&#xff0c;用于将 Java 对象与 JSON 数据相互转换。 configure 方法的作用是设置 ObjectMapper 的配置选项&#xff0c;例如设置日期格式、设置序列…...

面试热题(x的平方根)

给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和算符&#xff0c;例如 pow(x, 0.5) 或者 x ** 0.5 。 这道题虽然是简单题…...

食品溯源合约 -- 智能合约实例

前提 Roles: 实现对用户地址的角色权限管控,添加、删除角色。 Producer: 生产商角色管控。 ... FoodInfoItem: 食品信息管控。生产商、中间商、超市添加食品信息。 Trace:食品溯源合约,主要负责对以上几个合约的统筹协作。 Roles // SPDX-License-Identifier: MIT pragm…...

SAP系统中二代增强提供了4中增强函数的查找方法

1 Introduction The second enhancement is used widely by sap .We can set break-point in the function . The function is in the SMOD FG. 2 Detail SAP系统中二代增强提供了4中增强函数的查找方法&#xff1a; MODX_ALL_ACTIVE_MENUENTRIES (菜单增强) MODX_FUNCTION…...

RabbitMQ-SpringBoot2

1.依赖引用 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> 2.配置文件 spring: rabbitmq: host: 192.168.2.17 port: 5672 usernam…...

MyBatis核心 - SqlSession如何通过Mapper接口生成Mapper对象

书接上文 MyBatis – 执行流程 我们通过SqlSession获取到了UserMapper对象&#xff0c;代码如下&#xff1a; // 获取SqlSession对象 SqlSession sqlSession sqlSessionFactory.openSession();// 执行查询操作 try {// 获取映射器接口UserMapper userMapper sqlSession.get…...

【Git】标签管理与Git Flow模型

目录 一、操作标签 二、推送标签 三、删除标签 四、Git Flow模型分支设计 一、操作标签 git tag # 查看有哪些标签 git tag [name] # 给最近一次commit打标签 git tag [name] [commitID] #给指定的commit打标签 git tag -a [name] -m desc # 打标签并添加描述 二、推送标…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...