JWT --- 入门学习

news2024/12/26 20:05:42

1.常见的认证机制 

basic auth : 每次请求都会携带用户的username,password,易被黑客拦截。

Cookie auth : 我们请求服务器,创建一个session对象,客户端创建cookie对象。客户端每次访问,携带cookie对象。

(在当今,前后端分离中,通过前端服务器代理或反向代理,进行请求转发,从将cookie储存在客户端。)

oauth2 auth : 可以第三方登录,但是比较麻烦下去授权服务器获取授权码,再拿到token,再去访问资源服务。

token auth : 一般用户注册登录之后,生成token对象分别存储在数据库,以及客户端的localStore 或者 Cookie中。

 2.JWT 

jwt 全称 JSON Web Token ,简单来讲是一个拥有json格式的Token。

简单的理解:一种token的实现方式。

2.1 jwt组成

  •  Header:有令牌的类型和所使用的签名算法,如HMAC、SHA256、RSA;使用Base64编码组成;(Base64是一种编码,不是一种加密过程,可以被翻译成原来的样子)
{
	"alg" : "HS256",
	"type" : "JWT"
}
  • Payload :有效负载,包含声明;声明是有关实体(通常是用户)和其他数据的声明,不放用户敏感的信息,如密码。同样使用Base64编码
{
	"sub" : "123",
	"name" : "John Do",
	"admin" : true
}
  • Signature :前面两部分都使用Base64进行编码,前端可以解开知道里面的信息。Signature需要使用编码后的header和payload
  • 加上我们提供的一个密钥,使用header中指定的签名算法(HS256)进行签名。签名的作用是保证JWT没有被篡改过
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret);

2.2 jwt的优点和验证流程

2.2.1 优点

1.jwt对比与传统json和session不需要在服务端存储

2.负载中包含了用户所需要的信息,避免多次查询数据库

2.2.2 验证流程

  • 前端通过Web表单将自己的用户名和密码发送到后端的接口。该过程一般是HTTP的POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
  • 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT(Token)。
  • 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage(浏览器本地缓存)或sessionStorage(session缓存)上,退出登录时前端删除保存的JWT即可。
  • 前端在每次请求时将JWT放入HTTP的Header中的Authorization位。(解决XSS和XSRF问题)HEADER
  • 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确﹔检查Token是否过期;检查Token的接收方是否是自己(可选),验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

2.3 jwt快速入门

我们这里采用的jjwt实现。并且基于springboot项目实现的。

2.3.1 导入依赖

	<!--JWT 依赖-->
		<dependency>
			<groupId>io.jsonwebtoken</groupId>
			<artifactId>jjwt</artifactId>
			<version>0.9.1</version>
		</dependency>

2.3.2 生成jwt

这将信息加密成jwt。

 JwtBuilder jwtBuilder = Jwts.builder()
                // 声明的标识{"jti":"8888"} 唯一的
                .setId("8888")
                // 主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 创建日期  {"iat":"" }
                .setIssuedAt(new Date())
                // 用的什么编码
                .signWith(SignatureAlgorithm.HS256,"12345");
        // 拿到token
        String token = jwtBuilder.compact();

        System.out.println(token);
        System.out.println("---------------------");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        // 无法解密
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));

2.3.3 解析jwt

这个token需要自己替换成你生成的token。

 String token = "eyJhbGciOiJIUzI1NiJ9." +
                "eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY4NzIyODc0MX0." +
                "TiMu_sWRQxmlUtY-xh9G4G26UXYwGxID0kj6XC-iblI";
        // 解析token获取负载中声明的对象
        Claims claims = Jwts.parser()
               // 这里的签名秘钥
                .setSigningKey("12345")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id:"+claims.getId());
        System.out.println("subject:"+claims.getSubject());
        System.out.println("issuedAt:"+claims.getIssuedAt());

2.3.4 jwt过期校验

衔接上述生成和解析token代码。

我们在jwt代码中新加入,

  long now = new Date().getTime(); // ---新增
        long exp = now + 60 * 1000; // 设置60s后过期  // ---新增


        JwtBuilder jwtBuilder = Jwts.builder()
                // 声明的标识{"jti":"8888"} 唯一的
                .setId("8888")
                // 主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 发行日期  {"iat":"" }
                .setIssuedAt(new Date())
                // 用的什么编码, secret 这是解密的秘钥(!)
                .signWith(SignatureAlgorithm.HS256,"12345")
                // 设置token过期时间
                .setExpiration(new Date(exp)); // --- 新增

我们在解析token中,新加用来验证token过期时间,和生成时间。

PS:simpleDateFormat.format() 方法,内部没有校验null的逻辑,因此必须先生成jwt时,设置过期时间,否则为null,报异常。

  
        System.out.println("----------------------");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("jwt生成日期:"+simpleDateFormat.format(claims.getIssuedAt()));
        System.out.println("jwt过期日期:"+simpleDateFormat.format(claims.getExpiration()));
        System.out.println("当前日期:"+simpleDateFormat.format(new Date()));

2.3.4 自定义声明

我们可以在jwt中自定义claims,(这些信息会存入负载中)

衔接,上文。

        JwtBuilder jwtBuilder = Jwts.builder()
                // 声明的标识{"jti":"8888"} 唯一的
                .setId("8888")
                // 主体,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 发行日期  {"iat":"" }
                .setIssuedAt(new Date())
                // 用的什么编码去签名,12345 明文秘钥(secret)
                .signWith(SignatureAlgorithm.HS256,"12345")
                // 设置token过期时间
                .claim("role","admin");  // --- 新增
                // 直接传入map对象
                //.addClaims(new HashMap<>())

同样,我们也可以在解析token中获得到他。

        System.out.println(claims.get("role"));

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

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

相关文章

chatgpt赋能python:Python排队:提高效率、优化流程的神器

Python排队&#xff1a;提高效率、优化流程的神器 随着科技的不断进步&#xff0c;排队已经成为了现代生活中不可避免的一部分。在各个行业中&#xff0c;排队都是必须考虑的问题&#xff0c;包括餐馆、医院、机场和银行等等。针对排队问题&#xff0c;我们可以使用Python编程…

使用Vue + FormData + axios实现图片上传功能实战

前言 上节回顾 上一小节中&#xff0c;我们添加了Vue-router的路有数据&#xff0c;这些数据都将是后续实战课程中的真实路由数据了。同时引入了ElementUI的el-menu做为左侧菜单的组件&#xff0c;但本专栏的特点就是遇到第三方功能和组件&#xff0c;自己尽量也要实现一遍&a…

蓝牙ATT协议介绍

介绍 ATT&#xff0c;Attribute Protocol&#xff0c;用于发现、读、写对端设备的协议(针对BLE设备) ATT允许蓝牙远程设备&#xff08;比如遥控器&#xff09;作为服务端提供拥有关联值的属性集&#xff0c;让作为客户端的设备&#xff08;比如手机、电视&#xff09;来发现、…

【软件工程】软件工程期末考试试卷

瀑布模型把软件生命周期划分为八个阶段&#xff1a;问题的定义、可行性研究、软件需求分析、系统总体设计、详细设计、编码、测试和运行、维护。八个阶段又可归纳为三个大的阶段&#xff1a;计划阶段、开发阶段和( C)。 A、详细计划 B、可行性分析 C、 运行阶段 D、 测试与排…

JavaScript中的CRUD操作指南示例 - 用DHTMLX创建医院管理系统!

创建、读取、更新和删除(CRUD)是现代web和移动应用程序执行的四个基本功能。然而这些函数是如何产生的&#xff0c;它们到底是做什么的&#xff1f; 在本文中&#xff0c;我们将简要介绍CRUD的含义以及它何时被引入编程的。文中我们还将使用用于医院管理的JavaScript演示应用程…

图文并茂spring-boot3 热部署配置(IntelliJ IDEA 2023.1)

文章目录 &#x1f95a; 版本情况&#x1f9c2; 前言&#xff08;踩坑&#xff09;&#x1f357; 四步完成spring-boot热部署&#x1f957; 1、下载热部署模块&#x1f957; 2、application.yml 或者application.properties添加dev-tools配置&#x1f957; 3、settings中勾选条…

设计服务要考虑的7个维度

我在《软件设计的核心方法及实例解析》里提到软件设计的核心方法是分解和组合。分解粒度上&#xff0c;不同的架构师想法不一样&#xff0c;但是却有一点共性&#xff1a;设计一定要把不稳定的部分做封装&#xff0c;对外暴露稳定的部分&#xff0c;这也是有接口隔离这一原则的…

VS code 可以做什么?

编写 markdown VS code 真的是非常好用的Markdown编写工具&#xff0c;我用他来编写Markdown的时间甚至比写代码还要多。比如&#xff0c;我每周写的公众号文章。 相关插件&#xff1a; MarkdownMarkdown Preview EnhancedMarkdown All in One 编写python 大多数同学写pyth…

LLM - 基于 ChatGLM-6B 的工程配置搭建私有 ChatGPT 中文在线聊天

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131104546 Paper&#xff1a;GLM: General Language Model Pretraining with Autoregressive Blank Infilling 一篇于2022年发表在ACL会…

脑机接口科普0021——黑门01

本文禁止转载&#xff01;&#xff01;&#xff01;&#xff01; 我会在接下来的一段时间内&#xff0c;花一些章节&#xff0c;专门科普介绍一下《黑门》这部国产动漫。 科普《黑门》&#xff0c;源自网友看了我的脑机接口科普文章后&#xff0c;介绍我看黑门这个脑机接口科…

盘点那些 IT 技术面试官常用的 10 个挂人套路

最近几个朋友找我聊天&#xff0c;给我讲述了面试过程中遇到的一些不太理解的事情。作为一个技术面试官&#xff0c;今天来分享 10 个面试相关的套路。 1.自我介绍 自我介绍是一个重要的开始&#xff0c;好的开始是成功的一半。不需要太多花里胡哨的东西&#xff0c;简单、清…

86墙插双联明装新款:蓝奥声智能用电设备安全防护有多强

物理绝缘和智能数据分析安全技术重塑了墙壁插座的安全标准&#xff0c;极大可能规避日常生活中的意外&#xff0c;只有做到意外情况下也不会触电&#xff0c;这样的墙壁插座才能真正叫安全墙壁插座&#xff0c;“不触电且足够安全”应该成为墙壁插座的安全标配标准。 智能物理…

检测 ARP 欺骗

地址解析协议 &#xff08;ARP&#xff09; 是网络通信的基本推动因素。作为网络互联网层和网络链路层之间的桥梁&#xff0c;此网络协议将网络地址 &#xff08;IP&#xff09; 转换为物理层地址&#xff08;MAC 地址&#xff09;。ARP协议支持的地址转换在促进同一LAN中不同网…

给数据库构建一个展示界面

给mySQL构建一个展示界面 这是“构建个人小型医学数据库”系列文章的最后一部分。通过之前的工作我们确定了所要收集的各类变量并将其录入到mySQL数据库中。 为了展示MySQL中存储的数据&#xff0c;通过摸索我们最终使用appML、PHP和JavaScript开发一个展示页面。这些技术可以…

组合式API - provide和inject、Vue3小案例【Vue3】

组合式API - provide和inject 作用和场景&#xff1a;顶层组件向任意的底层组件传递数据和方法&#xff0c;实现跨层组件通信 跨层传递普通数据 顶层组件通过provide函数提供数据 provide(key, 顶层组件中的数据)底层组件通过inject函数获取数据 const message inject(key) …

每日学术速递6.14

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Realistic Saliency Guided Image Enhancement 标题&#xff1a;现实显着性引导图像增强 作者&#xff1a;S. Mahdi H. Miangoleh, Zoya Bylinskii, Eric Kee, Eli Shechtman, Ya…

js创建对象三种方式

创建对象三种方式 1、利用对象字面量创建对象2、利用 new Object 创建对象3、利用构造函数创建对象3.1 构造函数 1、利用对象字面量创建对象 const obj {name: 张三,age: 20 } console.log(obj)结果如下&#xff1a; 2、利用 new Object 创建对象 const obj new Object({…

Jmeter使用||接口测试实战

标题 Jmeter与postman一样&#xff0c;都可以用来进行接口测试。 前面的文章&#xff08; 测试工具介绍||Jmeter的简单使用&#xff09;&#xff0c;介绍了jmeter的下载、安装及简单使用。基于此背景&#xff0c;通过实例的形式&#xff0c;来介绍下如何利用jmeter进行接口测试…

Rancher集群containerd导出镜像

奇墨科技是国内领先的全域IT质量管理平台及服务商&#xff0c;创始团队为在ITSM、公有云&#xff0c;私有云&#xff0c;超融合及安全业务方向服务多年的业界精英团队&#xff0c;尤其具备领先的运维服务和业务理解能力&#xff0c;已服务了大量的世界及中国500强客户&#xff…

【深度学习】3-4 神经网络的学习- 学习算法的实现

神经网络的学习步骤如下所示&#xff1a; 步骤1(mini-batch) 从训练数据中随机选出一部分数据&#xff0c;目标是减小mini-batch的损失函数的值 步骤2(计算梯度) 为了减小mini-batch的损失函数的值&#xff0c;需要求出各个权重参数的梯度 步骤3(更新参数) 将权重参数沿梯度…