JWT---JSON Web Token

news2025/1/11 9:48:34

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的body
        JwtBuilder 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) {
        // 得到DefaultJwtParser
        Claims 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 {

    @Autowired
    private 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.coloradmin.cn/o/1375045.html

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

相关文章

Handsfree_ros_imu:ROS机器人IMU模块ARHS姿态传感器(A9)Liunx系统Ubuntu20.04学习启动和运行教程

这个是篇学习 Handsfree_ros_imu 传感器的博客记录 官方教程链接见&#xff1a; https://docs.taobotics.com/docs/hfi-imu/ 产品功能 IMU 内有 加速度计&#xff0c;陀螺仪&#xff0c;磁力计这些传感器&#xff0c;通过固定 imu 到物体上后&#xff0c;可以获取物体在运动…

登录模块的实现

一.前期的准备工作 1.页面的布局 (1)表单的校验: 利用element-ui提供的文档绑定rules规则后实现校验 (2)跨域的配置 &#xff1a; 利用proxy代理来解决跨域的问题 (3)axios拦截器的配置 两个点:1. 在请求拦截的成功回调中,如果token,因为调用其它的接口需要token才能调取。 在请…

锤科HandShaker修改版,支持安卓14、澎湃OS

如今几乎各家手机厂商都在布局生态&#xff0c;但PC端往往是最容易被忽略的一环&#xff0c;哪怕是很强的华为鸿蒙、小米澎湃&#xff0c;想要做到手机和电脑互联&#xff0c;也限制了笔记本机型 虽然我一直致力于解锁非小米电脑安装小米电脑管家&#xff0c;比如前几天刚刚更…

在WindowsServer2012中部署war项目

目录 前言 一.jdk安装 二.Tomact安装 三.MySQL安装 ​编辑​编辑​编辑​编辑​编辑​编辑​编辑 四.开放端口号 MySQL开放端口号 Tomact开放端口号 ​编辑 五.项目部署 1.将war放置在tomact中 2.配置项目sql脚本 3.最终效果 前言 安装Java开发工具包&#xff08…

【设计模式-02】Strategy策略模式及应用场景

一、参考资料 Java 官方文档 Overview (Java SE 18 & JDK 18)module indexhttps://docs.oracle.com/en/java/javase/18/docs/api/index.html Java中使用到的策略模式 Comparator、comparable Comparator (Java SE 18 & JDK 18)declaration: module: java.base, pa…

构建免费的Dokan和WooCommerce构建线上课程市场在线销售数字课程

我们知道创建良好的学习说明和材料很困难。但当涉及到销售时&#xff0c;就变得更加困难。如果您无法出售您的课程&#xff0c;那么没有什么比这更令人沮丧的了。 幸运的是&#xff0c;如果您使用的是 WordPress 网站&#xff0c;那么您可以非常轻松且免费地完成此操作。借助L…

java SSM物业管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM物业管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和 数据库&#xff0c;系统主要采用B/…

2024.1.11 Kafka 消息队列,shell命令,核心原理

目录 一 . 消息队列 二. Kafka 三 . 启动命令 四 . Kafka的Shell 命令 五 . Kafka的核心原理 1. Topic的分区和副本机制 2 . 消息存储机制 和 查询机制 3. Kafka中生产者数据分发策略 六 . Kafka 之所以具有高速的读写性能&#xff0c;主要有以下几个原因 七. 笔记…

指导AI进行推理:提示工程如何弥补RAG系统中的差距

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。 欢迎关注公众号(NLP Research) 原文标题:Instructing AI to Reason: How Prompt Engineering Bridges the Gap in RAG Systems 原文地址:https://medium.c…

vscode配置Todo Tree插件

一、在VSCode中安装插件Todo Tree ​​​​ 二、按下快捷键ctrlshiftP&#xff0c;输入setting.jspn 选择相应的配置范围&#xff0c;我们选择的是用户配置 Open User Settings(JSON)&#xff0c;将以下代码插入其中。 //todo-tree 标签配置从这里开始 标签兼容大小写字母(很…

MoE模型性能还能更上一层楼?一次QLoRA微调实践

Fine-Tuning Mixtral 8x7B with QLoRA&#xff1a;Enhancing Model Performance &#x1f680; 编者按&#xff1a;最近&#xff0c;混合专家(Mixture of Experts,MoE)这种模型设计策略展现出了卓越的语言理解能力&#xff0c;如何在此基础上进一步提升 MoE 模型的性能成为业界…

React 18中新钩子 useDeferredValue 使用

React是一个流行的用于构建用户界面的JavaScript库,它不断发展以为开发人员提供优化性能的工具。 React 18中引入的此类工具之一是useDeferredValue钩子,它旨在通过优先渲染更新来提高应用程序的性能。 useDeferredValue钩子是什么? useDeferredValue钩子是React性能优化工…

c++析构函数

析构函数的简述 1. 析构函数和构造函数类似&#xff0c;是c规定当对象的生命周期结束时&#xff0c;默认你会调用析构函数。 2. 同理&#xff0c;当我们不写析构函数的时候&#xff0c;编译器会自动生成一个空实现的析构函数。 3. 析构函数只能编译器自己调用&#xff0c;我们…

CSS3中transform2D变形详解

CSS3变形 在CSS3中&#xff0c;动画效果包括3个部分&#xff1a; 变形(transform)过渡(transition)动画(animation) 在实际开发中&#xff0c;有时需要实现元素的各种变形效果&#xff0c;如平移&#xff0c;缩放&#xff0c;旋转&#xff0c;倾斜等。 在CSS3中&#xff0c…

2 快速前端开发

CSS快速入门 1.CSS案例1.1 内容回顾1.2 案例&#xff1a;二级菜单1.2.1 划分区域1.2.2 搭建骨架1.2.3 Logo区域1.2.4 菜单部分 1.3 案例&#xff1a;顶部菜单 二级菜单小结 1.4 案例&#xff1a;推荐区域1.4.1 划分区域1.4.2 搭建骨架1.4.3 案例的实现小结 2. CSS知识点2.1 ho…

Spark on Hive及 Spark SQL的运行机制

Spark on Hive 集成原理 HiveServer2的主要作用: 接收SQL语句&#xff0c;进行语法检查&#xff1b;解析SQL语句&#xff1b;优化&#xff1b;将SQL转变成MapReduce程序&#xff0c;提交到Yarn集群上运行SparkSQL与Hive集成&#xff0c;实际上是替换掉HiveServer2。是SparkSQL…

基于自适应遗传算法的车间调度matlab仿真,可以任意调整工件数和机器数,输出甘特图

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 编码与初始化 4.2 适应度函数 4.3 遗传操作 4.4 自适应机制 4.5 终止条件 5.完整程序 1.程序功能描述 基于自适应遗传算法的车间调度matlab仿真,可以任意调整工件数和机器数,输出甘…

java基础之异常练习题

异常 1.Java 中所有的错误/异常都继承自 Throwable类&#xff1b;在该类的子类中&#xff0c; Error 类表示严重的底层错误&#xff0c; 对于这类错误一般处理的方式是 直接报告并终止程序 &#xff1b; Exception 类表示异常。 2.查阅API&#xff0c;完成以下填空&#xff1a;…

铭文 LaunchPad 平台 Solmash 推出早鸟激励计划

为感谢用户对Solmash的支持&#xff0c;Solmash 特别推出“Solmash早鸟激励计划”&#xff0c;以回馈社区的早期参与者&#xff0c;这是专为已经参与Staking Pool或Honest Pool的用户推出的激励。 Solmash NFT激励 被列入早鸟计划的用户&#xff0c;可通过点击&#xff1a;sol…

文件上传进阶绕过技巧(一)和靶场实战

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 0、环境准备 请移步《文件上传靶场实战&#xff1a;upl…