JWT 入门级教程

下面内容参考文章JWT详细讲解(保姆级教程)-阿里云开发者社区 (aliyun.com)

1.什么是JWT?

JSON Web Token(JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于作为 JSON 对象在各方之间安全地传输信息。此信息可以被验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用 HMAC 算法)或使用 RSAECDSA 的公钥/私钥对进行签名。

2.何时应使用 JSON Web 令牌?

  • 授权:这是使用 JWT 的最常见方案。用户登录后,每个后续请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小,并且能够轻松地跨不同域使用。
  • 信息交换:JSON Web 令牌是在各方之间安全传输信息的好方法。由于可以对 JWT 进行签名(例如,使用公钥/私钥对),因此您可以确定发送者是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

3.JWT结构(structure)

三部分组成,通过 . 分割开

  • Header
  • Payload
  • Signature
xxxxx.yyyyy.zzzzz

(1)Header

报头通常由两部分组成: Token的类型(即 JWT)和所使用的签名算法(如 HMAC SHA256或 RSA)。


{"alg": "HS256","typ": "JWT"
}

最终这个 JSON 将由base64进行加密(该加密是可以对称解密的),用于构成 JWT 的第一部分,eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9就是base64加密后的结果。

(2)Payload

Token的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和其他数据的语句。有三种类型的声明: registered claims, public claims, and private claims。

例如:

{"sub": "1234567890",// 注册声明"name": "John Doe",// 公共声明"admin": true // 私有声明
}

这部分的声明也会通过base64进行加密,最终形成JWT的第二部分。

registered claims(注册声明)

这些是一组预定义的声明,它们 不是强制性的,而是推荐的 ,以 提供一组有用的、可互操作的声明

例如:

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

注意:声明名称只有三个字符,因为 JWT 意味着是紧凑的。

Public claims(公共的声明)

使用 JWT 的人可以随意定义这些声明( 可以自己声明一些有效信息如用户的id,name等,但是不要设置一些敏感信息,如密码 )。但是为了避免冲突,应该在 JWT注册表中定义它们,或者将它们定义为包含抗冲突名称空间的 URI。

Private claims(私人声明)

这些是创建用于在同意使用它们的各方之间共享信息的习惯声明,既不是注册声明,也不是公开声明( 私人声明是提供者和消费者所共同定义的声明 )。

注意:对于已签名的Token,这些信息虽然受到保护,不会被篡改,但任何人都可以阅读。除非加密,否则不要将机密信息放在 JWT 的有效负载或头元素中。

(3)Signature

要创建Signature,您必须获取编码的标头(header)、编码的有效载荷(payload)、secret、标头中指定的算法,并对其进行签名。

例如,如果您想使用 HMAC SHA256算法,签名将按以下方式创建:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

上面的JSON将会通过HMACSHA256算法结合secret进行加盐签名(私钥加密),其中header和payload将通过base64UrlEncode()方法进行base64加密然后通过字符串拼接 "." 生成新字符串,最终生成JWT的第三部分SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了

(4) JWT的生成与解析

JWT输出是三个由点分隔的 Base64-URL 字符串,这些字符串可以在 HTML 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(如 SAML)相比更加紧凑。

真实情况,一般是在请求头里加入Authorization,并加上Bearer标注最后是JWT(格式:Authorization: Bearer <token>):

  • 通过Java代码实现JWT的生成( 使用的是JJWT框架 )

先导入JJWT的依赖(JJWT是JWT的框架)

        <!--JWT(Json Web Token)登录支持--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

测试代码如下:

public class JjwtTest {@Testpublic void generateToken() {// JWT头部分信息【Header】Map<String, Object> header = new HashMap<>();header.put("alg", "HS256");header.put("typ", "JWT");// 载核【Payload】Map<String, Object> payload = new HashMap<>();payload.put("sub", "1234567890");payload.put("name","John Doe");payload.put("admin",true);// 声明Token失效时间Calendar instance = Calendar.getInstance();instance.add(Calendar.SECOND,300);// 300s// 生成TokenString token = Jwts.builder().setHeader(header)// 设置Header.setClaims(payload) // 设置载核.setExpiration(instance.getTime())// 设置生效时间.signWith(SignatureAlgorithm.HS256,"secret") // 签名,这里采用私钥进行签名,不要泄露了自己的私钥信息.compact(); // 压缩生成xxx.xxx.xxxSystem.out.println(token);}
}

结果如下:

  • 通过Java代码实现JWT的解码( 使用的是JJWT框架 )
@Testpublic void getInfoByJwt() {// 生成的tokenString token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImV4cCI6MTY2MzI5NzQzMX0.Ju5EzKBpUnuIRhDG1SU0NwMGsd9Jl_8YBcMM6PB2C20";// 解析head信息JwsHeader jwsHeader = Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getHeader();System.out.println(jwsHeader); // {typ=JWT, alg=HS256}System.out.println("typ:"+jwsHeader.get("typ"));// 解析PayloadClaims claims =    Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getBody();System.out.println(claims);// {sub=1234567890, name=John Doe, admin=true, exp=1663297431}System.out.println("admin:"+claims.get("admin"));// 解析SignatureString signature =    Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getSignature();System.out.println(signature); // Ju5EzKBpUnuIRhDG1SU0NwMGsd9Jl_8YBcMM6PB2C20}

结果:

5.为什么不用session和cookie ,反而用token

基于session认证的登入系统存在的问题:

  • session

每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

  • 扩展性

用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

  • CSRF

因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

基于token的鉴权机制,就没有这些问题:

  • 基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

6.为什么使用JWT

  • 由于 JSON 没有 XML 那么冗长,所以当对它进行编码时,它的大小也更小,这使得 JWT 比 SAML 更加紧凑。这使得 JWT 成为在 HTML 和 HTTP 环境中传递的一个很好的选择。
  • 在安全性方面,SWT 只能由使用 HMAC 算法的共享秘密对称签名。但是,JWT 和 SAML Token可以使用 X.509证书形式的公钥/私钥对进行签名。与签名 JSON 的简单性相比,使用 XML 数字签名,签名 XML 而不引入模糊的安全漏洞是非常困难的。
  • JSON 解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML 没有自然的文档到对象映射。这使得使用 JWT 比使用 SAML 断言更容易。
  • 关于使用,JWT 是在 Internet 规模上使用的。这突出了在多个平台(尤其是移动平台)上对 JSON Web 令牌进行客户端处理的便利性。

总结

安全相关

  • 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
  • 保护好secret私钥,该私钥非常重要。
  • 如果可以,请使用https协议

作者:Dearmadman
链接:https://www.jianshu.com/p/576dbf44b2ae
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

JWT详细讲解(保姆级教程)-阿里云开发者社区 (aliyun.com)

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

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

相关文章

Angular系列教程之路由守卫

文章目录 前言路由守卫的类型CanLoadCanActivateCanActivateChildCanDeactivateResolve总结 前言 在Angular中&#xff0c;路由守卫是一个非常有用的功能&#xff0c;可以帮助我们控制用户在导航过程中的权限和访问限制。通过使用路由守卫&#xff0c;我们可以拦截导航并根据需…

python PyQt5的学习

一、安装与配置 1、环境&#xff1a; python3.7 2、相关模块 pip install pyqt5 pyqt5-tools pyqt5designer 可以加个镜像 -i https://pypi.tuna.tsinghua.edu.cn/simple3、配置设计器 python的pyqt5提供了一个设计器&#xff0c;便于ui的设计 界面是这样的&#xff1a…

MFC为资源对话框添加消息处理函数和初始化控件

现在我VC6新建了一个对话框工程&#xff1b;又在资源添加了一个新的对话框&#xff0c;并为新的对话框添加了名为CTestDlg的类&#xff1b; 在主对话框的cpp文件包含#include "TestDlg.h"&#xff1b; 在主对话框的cpp文件的OnInitDialog()成员函数中&#xff0c;添…

单列的堆叠柱状图

目的 MSingleColumnStackBarChart类被设计用于创建只有单列的堆叠柱状图&#xff0c;用于血糖数据的统计。以下是封装这个类的目的的详细描述&#xff1a; 抽象复杂性&#xff1a; 通过创建MSingleColumnStackBarChart类&#xff0c;你将复杂的MPAndroidChart库的使用和配置封…

React全局状态管理

redux是一个状态管理框架&#xff0c;它可以帮助我们清晰定义state和处理函数&#xff0c;提高可读性&#xff0c;并且redux中的状态是全局共享&#xff0c;规避组件间通过props传递状态等操作。 快速使用 在React应用的根节点&#xff0c;需要借助React的Context机制存放整个…

mobi文件怎么转换成pdf?

mobi文件怎么转换成pdf&#xff1f;在数字化时代&#xff0c;电子书籍成为了越来越受欢迎的阅读方式。我们可以通过多种格式的电子书来获取知识和娱乐&#xff0c;其中一种常见的格式就是Mobi文件。Mobi文件是亚马逊公司开发的一种电子书格式&#xff0c;它主要用于Kindle设备和…

SL4010升压恒压电源芯片DC3.7V升压5V、12V、24V/5A

SL4010是一款升压恒压电源芯片&#xff0c;可以将DC3.7V的输入电压升压至5V、12V或24V的输出电压&#xff0c;并可提供高达5A的输出电流。这款芯片采用了先进的升压技术&#xff0c;能够实现高效、稳定的电压转换&#xff0c;同时还具有低噪声、低功耗和低成本等优点。在各种需…

【论文阅读】Consistency Models

文章目录 IntroductionDiffusion ModelsConsistency ModelsDefinitionParameterizationSampling Training Consistency Models via DistillationTraining Consistency Models in IsolationExperiment Introduction 相比于单步生成的模型&#xff08;例如 GANs, VAEs, normalizi…

推荐几个Github高星GoLang管理系统

在Web开发领域&#xff0c;Go语言&#xff08;Golang&#xff09;以其高效、简洁、高并发等特性逐渐成为许多开发者的首选语言。有许多优秀的Go语言Web后台管理系统&#xff0c;这些项目星星众多&#xff0c;提供了丰富的功能和良好的代码质量。本文将介绍一些GitHub高星的GoLa…

学会这个昼夜系统,你也能做出一款饥荒生存类游戏DEMO!

学会这个昼夜系统&#xff0c;你也能做出一款饥荒生存类游戏DEMO&#xff01; 《饥荒》作为生存类游戏的老大哥&#xff0c;深受大家喜爱&#xff0c;这款游戏于2012年年底正式公测上线&#xff0c;距今已有10年的时间&#xff0c;从最初的单机版慢慢推出了联机版&#xff0c;…

Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务

技术背景 我们在对接Unity下推送模块的时候&#xff0c;遇到这样的技术诉求&#xff0c;开发者希望在Android的Unity场景下&#xff0c;获取到前后摄像头的数据&#xff0c;并投递到RTMP服务器&#xff0c;实现低延迟的数据采集处理。 在此之前&#xff0c;我们已经有了非常成…

大模型学习之书生·浦语大模型5——基于LMDeploy大模型量化部署实践

目录 大模型部署背景 LMDeploy部署 量化 TurboMind API server 动手实践环节

LCR 173. 点名(二分)

一、题目描述 LCR 173. 点名 某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席&#xff0c;请返回他的学号。 示例 1: 输入: records [0,1,2,3,5] 输出: 4示例 2: 输入: records [0, 1, 2, 3, 4, 5, 6, 8] 输出: 7 二、题目解析…

flink1.14.5使用CDH6.3.2的yarn提交作业

使用CDH6.3.2安装了hadoop集群&#xff0c;但是CDH不支持flink的安装&#xff0c;网上有CDH集成flink的文章&#xff0c;大都比较麻烦&#xff1b;但其实我们只需要把flink的作业提交到yarn集群即可&#xff0c;接下来以CDH yarn为基础&#xff0c;flink on yarn模式的配置步骤…

Resemble Enhance音频失真损坏修复AI工具:一个开源语音超分辨率AI模型

Resemble Enhance是一款强大的音频处理工具&#xff0c;可以将嘈杂的录音转化为清晰而有力的声音&#xff0c;为用户提供更优质的听觉体验。这个工具不仅可以有效去除录音中的各种噪声和杂音&#xff0c;还能够恢复音频失真并扩展音频带宽&#xff0c;使原本的声音听起来更加清…

高级分布式系统-第10讲 分布式控制系统

高级分布式系统汇总&#xff1a;高级分布式系统目录汇总-CSDN博客 自动化是关于一切人造系统自动、智能、自主、高效和安全运行的科学与技术 计算机控制技术是实现自动化的主要方法和手段 分布式控制技术是伴随着机器大工业生产而诞生的特殊计算机控制技术 计算机控制系统 …

Qt/QML编程之路:使用camera摄像头(35)

汽车应用中,camera起到了越来越多的作用,数字化的作用,这点无可争议,而作为GUI设计工具,如何让Camera类的应用能更好的发挥作用呢? You can use Camera to capture images and movies from a camera, and manipulate the capture and processing settings that get appl…

网站防御爬虫攻击有哪些方式

很多网站都深受爬虫困扰&#xff0c;网站在被爬虫大量抓取的的时候经常容易被爬虫把服务器资源抓崩了&#xff0c;有的时候&#xff0c;同行也会来爬取我们网站进行数据采集&#xff0c;影响我们站点的原创性&#xff0c;那么如何进行相对应的防护还是非常重要的&#xff01; …

mysql新增用户密码控制局域网访问权限

方法一、通过navicat中sql语句新增 CREATE USER usernamelocalhost IDENTIFIED BY password; GRANT ALL PRIVILEGES ON *.* TO usernamelocalhost WITH GRANT OPTION; FLUSH PRIVILEGES;把其中的username和password改成自己的即可 如果将上面的localhost改成%&#xff0c;则这…

从CISC到RISC-V:揭开指令集的面纱

对于大多数同学来说&#xff0c;计算机或智能手机的运行似乎就像魔法一样神奇。你可能知道它们内部都是一些复杂的电子组件&#xff0c;比如CPU、内存等等&#xff0c;但这些组件是如何协同工作&#xff0c;让我们可以在电脑上打字&#xff0c;或者在手机上看视频呢&#xff1f…