JWT---JSON Web Token

JSON Web Token是什么

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

JSON Web Token的结构是什么样的

JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:

  • Header
  • Payload
  • Signature

token格式:head.payload.singurater 如:xxxxx.yyyy.zzzz

package com.sky.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;public class JwtUtil {/*** 生成jwt* 使用Hs256算法, 私匙使用固定秘钥** @param secretKey jwt秘钥 itcast* @param ttlMillis jwt过期时间(毫秒) 7200000* @param claims    设置的信息* @return*/public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {// 指定签名的时候使用的签名算法,也就是header那部分SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成JWT的时间long expMillis = System.currentTimeMillis() + ttlMillis;Date exp = new Date(expMillis);// 设置jwt的bodyJwtBuilder builder = Jwts.builder()// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的.setClaims(claims)// 设置签名使用的签名算法和签名使用的秘钥.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))// 设置过期时间.setExpiration(exp);return builder.compact();}/*** Token解密** @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个* @param token     加密后的token* @return*/public static Claims parseJWT(String secretKey, String token) {// 得到DefaultJwtParserClaims claims = Jwts.parser()// 设置签名的秘钥.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))// 设置需要解析的jwt.parseClaimsJws(token).getBody();return claims;}}

测试

public class JWTMain {public static void main(String[] args) {Map<String, Object> map=new HashMap<String, Object>();map.put("aaa",222);String jwt = JwtUtil.createJWT("itcast", 7200000, map);System.out.println(jwt);System.out.println("*********************");Claims parseJWT = JwtUtil.parseJWT("itcast", "eyJhbGciOiJIUzI1NiJ9.eyJhYWEiOjIyMiwiZXhwIjoxNzA0ODk5MjkzfQ.w-VSPBjOQjLRy2ARB_JGKQwe0_dRIgvX6Owprk2P71g");System.out.println(parseJWT);}

jwt令牌校验的拦截器

@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {@Autowiredprivate JwtProperties jwtProperties;/*** 校验jwt** @param request* @param response* @param handler* @return* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}//1、从请求头中获取令牌String token = request.getHeader(jwtProperties.getAdminTokenName());//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());log.info("当前员工id:", empId);BaseContext.setCurrentId(empId);//ThreadLocal.set()可以保存当前线程的信息,为本线程的全局变量,可以通过ThreadLocal.get()获取//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}}
}

基于Token的身份认证

HTTP协议是无状态的,也就是说,如果我们已经认证了一个用户,那么他下一次请求的时候,服务器不知道我是谁,我们必须再次认证。
传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。
这种基于服务器的身份认证方式存在一些问题:

  • Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
  • Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。
  • CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。
  • CSRF : 用户很容易受到CSRF攻击。

JWT与Session的差异 相同点是,它们都是存储用户信息;然而,Session是在服务器端的,而JWT是在客户端的。
基于Token的身份认证是无状态的,服务器或者Session中不会存储任何用户信息。
没有会话信息意味着应用程序可以根据需要扩展和添加更多的机器,而不必担心用户登录的位置。
虽然这一实现可能会有所不同,但其主要流程如下:

  • 用户携带用户名和密码请求访问
  • 服务器校验用户凭据
  • 应用提供一个token给客户端
  • 客户端存储token,并且在随后的每一次请求中都带着它
  • 服务器校验token并返回数据

注意:每一次请求都需要token -Token应该放在请求header中 -我们还需要将服务器设置为接受来自所有域的请求,用Access-Control-Allow-Origin: *
v2-7789057d5744891fdf3366d7887ab6e8_r.jpg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/614225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QTableView如何设置显示风格?

1. 利用样式表设定样式风格 QTableView 控件本身没有直接的显示风格设置。然而&#xff0c;您可以通过使用样式表来自定义 QTableView 的外观&#xff0c;以实现不同的显示风格。以下是一些样式属性和伪状态类&#xff0c;您可以在样式表中使用来自定义 QTableView 的显示风格…

【每日一题】构造有效字符串的最少插入数

文章目录 Tag题目来源解题思路方法一&#xff1a;考虑 abc 的个数 写在最后 Tag 【字符串】【2024-01-11】 题目来源 2645. 构造有效字符串的最少插入数 解题思路 方法一&#xff1a;考虑 abc 的个数 思路 如果答案由 t 个 “abc” 组成&#xff0c;那么需要插入字符个数为…

QEMU源码全解析 —— PCI设备模拟(3)

接前一篇文章&#xff1a; 2. PCI设备的模拟 QEMU模拟的设备很多都是PCI设备&#xff0c;本节介绍PCI设备的模拟。与所有设备类似&#xff0c;PCI设备的父设备也是TYPE_DEVICE&#xff0c;其定义在QEMU源码根目录/hw/pci/pci.c中&#xff0c;代码如下&#xff1a; static con…

概率论与数理统计-第7章 假设检验

假设检验的基本概念 二、假设检验的基本思想 假设检验的基本思想实质上是带有某种概率性质的反证法&#xff0c;为了检验一个假设H0,是否正确&#xff0c;首先假定该假设H0正确&#xff0c;然后根据抽取到的样本对假设H0作出接受或拒绝的决策&#xff0c;如果样本观察值导致了…

二叉树的创建与遍历

对于前序遍历&#xff0c;首先访问当前节点&#xff0c;然后递归地遍历左子树和右子树。 这就是为什么前序遍历的代码中&#xff0c;首先是 printf("%d ", root->data);。中序遍历&#xff1a; 对于中序遍历&#xff0c;首先递归地遍历左子树&#xff0c;然后访问…

js 捕获 await 的报错

函数封装 func.js // 捕获 await 的错误 export const to (promise, errorExt, ) > {return promise//成功&#xff0c;则error返回null&#xff0c;result返回data.then((data) > [null, data])//错误则捕获错误内容&#xff0c;然后返回错误信息&#xff0c;result为u…

leetcode-x的平方根

69. x 的平方根 此题使用二分法做 class Solution:def mySqrt(self, x: int) -> int:left 1right xwhile left < right:mid (left right) // 2if x mid ** 2:return midelif x > mid ** 2:left mid 1else:right mid - 1return right

JavaScript 中 0.1 + 0.2 != 0.3:浮点数运算的陷阱

引言 在日常的 JavaScript 开发中&#xff0c;我们经常会面对一些看似简单的数学运算。然而&#xff0c;当我们执行 0.1 0.2 这样的操作时&#xff0c;很多人可能会感到困惑&#xff0c;因为预期的结果应该是 0.3&#xff0c;但实际上却是一个略微不同的值。这个现象是由于 J…

5、C语言:结构

结构 结构的基本知识结构与函数传递结构 结构数组、指向结构的指针自引用结构&#xff08;二叉树&#xff09;表查找类型定义&#xff08;typedef&#xff09;联合位字段 结构也是一种数据类型。类似于int、char、double、float等。 结构是一个或多个变量的集合&#xff0c;这些…

c++学习笔记-STL案例-机房预约系统1-准备工作

前言 准备工作包括&#xff1a;需求分析、项目创建、主菜单实现、退出功能实现 目录 1 机房预约系统需求 1.1 简单介绍 1.2 身份介绍 1.3 机房介绍 1.4 申请介绍 1.5 系统具体要求 1.6 预约系统-主界面思维导图 2 创建项目 2.1 创建项目 2.2 添加文件 ​编辑 3 创建…

页面跳转后,默认选中tree节点并高亮显示

1.场景 操作步骤&#xff1a; 1.点击数据连接数&#xff0c;打开弹窗 2.点击连接状态跳转到数据连接模块 3.默认选中tree的数据源id节点 2.代码 参数解释&#xff1a; 3.实现逻辑 首先将id通过组件传参的方式传过去&#xff0c;数据连接接收后&#xff0c;在tree里设置…

ubuntu 挂载新硬盘

1、检测新硬盘 新增加硬盘&#xff0c;检测硬盘识别情况。 命令检查&#xff1a;sudo fdisk -l 3、格式化磁盘 格式化&#xff1a;sudo mkfs.ext4 /dev/sdb 其中&#xff0c;/dev/sdb是新分区的设备文件名&#xff0c;ext4是要使用的文件系统类型。 4、挂载新分区 sudo mk…

【银行测试】24年金融银行项目,10道高频测试面试题汇总...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 面试题1&#xff…

使用AUTOSAR来开发汽车基础软件的优点

1、高质量。以前我们采用手写代码的方式&#xff0c;是几个工程师在战斗。现在我们采用平台&#xff0c;BSW代码都是供应商提供的&#xff0c;我们相当于后面还有一个团队陪着我们在战斗。 2、低成本。大家都说采用AUTOSAR平台好贵&#xff0c;但是从长远来看是值得的&#xff…

计算机毕业设计----ssm开发的Java快递代拿系统

使用技术 采用 Spring SpringMVC MyBatisPlus&#xff0c;连接池采用 Druid&#xff0c;安全框架使用 Shiro&#xff0c;前端采用 Bootstrap layer 实现。 支付采用支付宝沙箱环境&#xff0c;支付APP下载链接&#xff0c;[点击这里](https://sandbox.alipaydev.com/user/…

SpringBoot中使用SpringEvent业务解耦神器实现监听发布事件同步异步执行任务

场景 SpringBoot中使用单例模式ScheduledExecutorService实现异步多线程任务(若依源码学习)&#xff1a; SpringBoot中使用单例模式ScheduledExecutorService实现异步多线程任务(若依源码学习)-CSDN博客 设计模式-观察者模式在Java中的使用示例-环境监测系统&#xff1a; 设…

GPT实战系列-简单聊聊LangChain

GPT实战系列-简单聊聊LangChain LLM大模型相关文章&#xff1a; GPT实战系列-ChatGLM3本地部署CUDA111080Ti显卡24G实战方案 GPT实战系列-Baichuan2本地化部署实战方案 GPT实战系列-大话LLM大模型训练 GPT实战系列-探究GPT等大模型的文本生成 GPT实战系列-Baichuan2等大模…

SpringBoot中使用LocalDateTime踩坑记录

文章目录 前言一、为什么推荐使用java.time包的LocalDateTime而不是java.util的Date&#xff1f;二、使用LocalDateTime和LocalDate时遇到了哪些坑&#xff1f;2.1 Redis序列化报错2.1.1 问题现象2.1.2 问题分析2.1.3 解决方案 2.2 LocalDateTime和LocalDate类型的属性返回给前…

分享一个实现侧滑菜单的Flutter页面所遇到的问题与解决思路

最近做了一个需要实现侧滑菜单相关的Flutter新页面&#xff0c;页面布局结构稍微比较复杂。因此&#xff0c;做完之后就对研发的过程做出一些整理。 以下主要整理跟侧滑菜单相关的内容。直奔主题&#xff0c;首先&#xff0c;要实现侧滑菜单&#xff0c;有以下几个方案。而本次…

类型特质和静态断言

static_assert( constant-expression, string-literal );static_assert( constant-expression ); // C17 (Visual Studio 2017 and later) constant-expression 可以转换为布尔值的整型常量表达式。 如果计算出的表达式为零 (false)&#xff0c;则显示 string-literal 参数&…