JWT 介绍 - Step by Step

翻译自 Mohamad Lawand 2021年3月11日的文章 《Intro to JWT - Step by Step》 [1]

在本文中,我将向您介绍 JWT[2]

我们今天要讲的内容包含:

  • JWT 是什么

  • 我们应该在什么时候使用它

  • JWT 与 Session Id 比较

  • JWT 结构

  • JWT 签名

JWT 是什么

JWT (JSON Web Token) 是一个开放标准[3],它定义了一种以紧凑和自包含的方法,用于在双方之间安全地传输编码为 JSON 对象的信息。

因此,简单来说,它是 JSON 格式的加密字符串,其中包含敏感信息,它使我们能够验证不同服务间的发送者。

应该在什么时候使用 JWT?

  • 授权: 这是使用 JWT 最常见的场景。JWT 用于授权而非身份验证。通过身份验证,我们验证用户名和密码是否有效,并将用户登录到系统中。通过授权,我们可以验证发送到服务器的请求是否属于通过身份验证登录的用户,从而可以授予该用户访问系统的权限,继而批准该用户使用获得的 token 访问路由、服务和资源。

  • 信息交换: JSON Web Token 是在双方之间安全地传输信息的一种好方法。因为 JWT 可以被签名(例如,使用公钥/私钥对),所以使您能确保发送方是他们所声称的那一方。此外,由于签名是使用 Header 和 Payload 计算的,因此还使您能验证发送的内容没有被篡改。

JWT 与 Session Id 比较

§小型 Web 应用程序

Session Id 实现

在传统的 Web 应用程序中,我们使用 Session 来授权用户,当用户登录到应用程序后,我们会为该用户分配一个唯一的 Session Id。我们将此 Session Id 保存在用户浏览器的安全 cookie 中和服务器的内存中。我们对每个请求都使用相同的会话,以便服务器知道该用户已通过身份验证。对于每个请求,cookie 中的 Session Id 都会与服务器内存中的 Session Id 作匹配,以验证用户是否被授权。

JWT 实现

在 JWT 实现中,我们使用 JWT 授权用户,当用户登录到应用程序后,就会为每个通过身份验证的用户生成一个唯一的 JWT。我们将该 token 保存在浏览器的 local storage 或者 cookie 中,而不会在服务器端保存任何内容。对于每个请求,该 token 都会被发送到服务器进行解密和验证,以核实该用户是否已授权,不管以何种方式篡改了 token 都会被拒绝。

这种实现对于小型站点来说很好,仅仅因为我们不再存储 Session Id,从而通过减少服务器的负载,我们已经从 JWT 中看到了一些好处。

§高级 Web 应用程序(多个服务器)

如果我们的应用程序越来越受欢迎,需要我们对其进行扩展,会发生什么呢?

Session Id 实现

我们需要有一台连接到负载均衡器的新服务器,以便基于流量和可用性在 Web 服务器之间导航流量。这种实现给我们带来了一个新的问题,如下所示:

如果用户 1 登录到了服务器 1,那么服务器 1 已经将 session 保存在其内存中,当用户 1 发出另一个请求并且负载均衡器将该请求重定向到了服务器 2,而服务器 2 没有保存该 session 信息,这时会发生什么情况?

用户将被认为已退出应用程序并被要求再次登录,这不是一个好的用户体验。通常,我们解决这个问题的方法是引入缓存:

现在,所有的 Session 也将同时保存在缓存中,因此任何一台服务器都可以检查该 Session 是否存在,并可以利用它来验证用户并授予他们对应用程序的访问权限。

尽管缓存解决了我们的问题,但是在生产环境中,这种解决方案有着昂贵的成本:

  • 需要大量的 RAM、CPU、存储来跟踪所有这些会话和平稳地处理请求

  • 需要维护缓存,以确保没有幽灵会话或无效会话

  • 万一某台服务器崩溃,所有未与缓存同步的会话都会丢失

  • 使用户无效更复杂

  • 托管成本高

JWT 实现

让我们来看看如何通过 JWT 实现来处理相同的情况。

不同于在 Cookie 中使用 Session Id 与服务器内存中的 Session 作匹配;我们可以使用 JWT 来代替它。此时,当用户登录到我们的应用程序时,服务器将不会生成 Session Id 并将其保存在内存中,而是会创建一个 JWT token,并对其进行编码和序列化,然后使用自己的加密机制对其进行签名。通过这种方式,服务将知道一旦对它做了变更或篡改,便将其变为无效。由于通过服务器的加密机制对其进行了签名,所以这是可以被检验的。

使用 JWT 可以更容易地管理可伸缩性,因为我们不需要服务器来处理任何会话检查或缓存检查。请求可以转发到负载均衡器为其分配的任一服务器,而无需担心会话的可用性。万一某台服务器宕机,所有的 token 将仍然有效,因为所有服务器上的加密机制是一样的。

§JWT 和 Session Id 的区别总结

让我们来快速总结一下 JWT 和 Session Id 的区别

JWT

  • 服务器上不保存任何东西,JWT 存储于客户端中

  • 由服务器加密和签名

  • token 包含用户的所有信息

  • 所有信息都存储于 token 本身中

  • 易于缩放

Session Id

  • Session Id 保存于服务器和客户端中

  • 加密并签名

  • Session Id 是对用户的引用

  • 服务器需要查找用户并进行必要的检查

  • 难以缩放

JWT 结构

JSON Web Token 由三部分组成,以点(.)分隔,分别是:

  • Header(标头)

  • Payload(有效负载)

  • Signature(签名)

因此,JWT 通常如下所示:

xxxxxx.yyyyyyy.zzzzzzzz

这种分隔使从视觉上更容易看出 token 的不同部分。让我们来分解一下它的不同的部分。

§Header

Header 通常由两部分组成:

  • token 的类型,这里是 JWT

  • 使用的签名算法,比如 HMAC、SHA256 或 RSA。

例如:

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

然后,将此 JSON 以 Base64Url 编码,形成 JWT 的第一部分。

§Payload (Data)

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

  • Registered Claims:这是一组非强制性的但建议使用的预定义 Claims,以提供一组有用的、可互操作的 Claims。其中包含:iss (issuer,签发者)、exp (expiration time,过期时间)、sub (subject,主题)、aud (audience,受众) 等等。

  • Public Claims:这些可以由使用 JWT 的人员随意定义。但是为了避免冲突,应该在 IANA JSON Web Token Registry 中定义它们,或者将其定义为包含抗冲突命名空间的 URI。

  • Private Claims:这些是自定义声明,是为了在同意使用它们的双方共享信息而创建的,它们既不是注册的声明,也不是公共的声明。

举一个有效负载的例子:

{"sub": "221122112","name": "Mohamd Lawand","admin": true,"exp": 15323232,"iat": 14567766 // 该 token 的签发时间
}

然后,对有效负载进行 Base64Url 编码,形成 JSON Web Token 的第二部分。

除非将其加密,否则请不要将机密信息放入 JWT 的 Payload 或 Header 元素中。

签名

签名使我们能够验证 token 是否有效和没被篡改。它的工作方式是获取 token 的前两部分,将 Header 和 Payload 分别编码为 Base64,然后将它们用 “.” 连接起来。这样我们就拥有了与用户共享的所有数据。

然后,获取在第一部分(Header)中提供的算法并应用于上面的连接结果。如果前两部分的哈希结果与 token 的第三部分匹配,则表示此 JWT 是有效的;如果不匹配,则表示此 token 被修改过,是无效的。

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

这种方案的唯一威胁是密钥在服务器以外的任何地方都可用。但是,如果我们保护好密钥的安全,就没有什么能损害这一过程。

签名被用于验证消息在传输过程中没有被篡改,而且,当 token 是使用私钥签名时,它还可以验证 JWT 发送方的真实身份。

它的工作原理与密码哈希非常相似——我们将两部分组合在一起,并且使用特定的算法进行单向哈希,然后我们比较哈希的结果看它们是否有效。

§签名方式

现在,让我们来看一下对 JWT 进行签名的方式:

  • 一个 secret(使用 HMAC 算法)

  • 一个 公钥/私钥对(使用 RSA 或 ECDSA)

签名的 token 可以验证其中包含的 Claims 的完整性,而加密的 token 则可以向其他方隐藏这些 Claims。


相关链接:

  1. https://dev.to/moe23/intro-to-jwt-mcb Intro to JWT - Step by Step ↩︎

  2. https://jwt.io/ jwt.io ↩︎

  3. https://tools.ietf.org/html/rfc7519 RFC 7519 ↩︎

作者 :Mohamad Lawand
译者 :技术译民
出品 :技术译站(https://ITTranslator.cn/)

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

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

相关文章

Helpdesk 流程

最近Fox的公司部署了新的Helpdesk系统。为了让用户从原来打电话和发邮件寻求IT员工帮助的方式转变为使用Helpdesk系统提交tickets,需要制定和规范Helpdesk流程,小小推动下ITIL进程。 HelpDesk系统与AD集成。公司用户可以使用域用户名和密码登陆Helpdesk系…

vscode 快速调到定义处_vim技巧:在程序代码中快速跳转,在文件内跳转到变量定义处...

本篇文章介绍 vim 的一些使用技巧:在程序代码中快速跳转在文件内跳转到变量定义处在程序代码中快速跳转在 vim 中查看代码文件时,可以使用下面命令在程序代码中快速跳转,提高效率。%跳转到光标所在括号的另一个配对括号上,适用于小…

震撼!英伟达用深度学习做图像修复,毫无ps痕迹

在计算机视觉研究领域,NVIDIA常常让人眼前一亮。比如“用Progressive Growing的方式训练 GAN,生成超逼真高清图像”,“用条件 GAN 进行 2048x1024 分辨率的图像合成和处理”的pix2pixHD项目,或者脑洞大开的让晴天下大雨、小猫变狮…

程序员过关斩将--重复的请求并不好过滤

为什么要做重复请求的过滤呢?不过滤不行吗?过滤重复请求很难吗?加一个请求ID不就好了吗?每个技术难点的话题,肯定是由一个产品需求引发的,俗话说:如果没有产品经理,程序员将不需要听…

.NET团队送给.NET开发人员的云原生学习资源

企业正在迅速采用云的功能来满足用户需求,提高应用程序的可伸缩性和可用性。要完全拥抱云并优化节约成本,就需要在设计应用程序时考虑到云的环境,也就是要用云原生的应用开发方法。这意味着不仅要更改应用程序的构建方式,还要更改…

深夜,学妹说她想做Python数据分析师

大家好,我是大鹏,目前是一名数据分析师。上周末晚上,我的学妹突然约我出来喝咖啡。想起学妹在学校就一直说想转行,最近在网上捣鼓自学数据分析软件有一小段时间了。我想她不是为了叙旧。果然来到咖啡店,她一屁股坐下来…

在真实工作中的编程是怎么样的,与学校里有什么不同?

学校里每门编程语言课程都是上一点上不完的,实验课写的代码最长一两百行。 而在真实的工作环境中,程序员写代码是怎么样的?每天要啪啪啪手敲成千上万行代码嘛?和在学校学习时写代码有什么异同呢?/*说说我的经验*/刚进公…

聊一聊Docker与时区

前言 当我们把应用部署到容器里面之后,基本都会要和时间/时区打交道!!大部分的应用,多多少少都会有获取当前时间的操作,试想一下应用拿到的时间不对,那么业务极有可能会乱套,造成严重的损失。时…

百度竟然不是中国的

2019独角兽企业重金招聘Python工程师标准>>> 身份之谜—百度是中国公司吗? 虽然,Baidu在美国上市使用了“中国的Google”这么一个概念,说真的,我知道的Baidu和Google最大的共同点也许就是他们都是美资公司。Baidu公司…

tortoisegit图标消失_安装TortoiseGit 状态图标不能正常显示

如果你安装 TortoiseSVN 之后,功能使用正常,但是文件夹或文件左上角就是不显示图标,那么你可能1. 64bit 系统上装了 32bit 的 TortoiseSVN解决方法是,再安装 64bit 的 TortoiseSVN,两者可并行运行2. Windows Explorer …

好用的验证框架FluentValidation(上)

把数据错误扼杀在早期,那就是在数据的入口处,一般数据都是打包成一个实体的方式进传递,FluentValidation就以实体类为单位进行属性验证的集合。Install-Package FluentValidation下面看一个例子吧。实体类:public class Person {p…

10G 职场晋升/IT干货/生活技能/理财秘籍 【全套】学习资料免费送!

你的同龄人正在抛弃你,大学毕业后五年,你就会发现,同龄人之间的差距已经是云泥之别。当年一起追剧,一起逃课,一起吹牛的同学,有人已经年薪百万,有人还在抢两块钱的红包。有人去过许多国家&#…

iNeuOS工业互联平台,发布消息管理、子用户权限管理、元件移动事件、联动控制、油表饼状图和建筑类设备驱动,v3.4版本...

目 录1. 概述... 22. 平台演示... 23. 消息管理... 24. 子用户权限管理... 35. 元件移动事件... 36. 联动控制... 47. 增加油表和饼图... 58. 增加住建部DL/T645和智能液位计协议驱动1. 概述发布iNeuOS 3.4版本,主…

程序猿看段子,越看越心碎!

程序员整天面对代码,压力一定很大吧~小编表示应该时不时也给你们来点段子,增加一下生活的乐趣,让你们看到希望的曙光...今天整理的10个段子,你们绝对喜欢。看看就知道啦!【一直有人问我,程序员应该看什么书…

mysql写入监控_zabbix 自定义key 监控mysql增删查改

vim /etc/zabbix/zabbix_agentd.d/mysql.conf##zabbix_agentd.d在这个文件夹下的.conf,都会被agent读取,我们这里新建的一个配置文件方便使用,这样就不需要去动主配置文件了UserParameterecho[*],echo "$1"#要传递参数要带[*],且ke…

自制H3C交换机CONSOLE线

单位有一台H3C S3600交换机,手痒痒的想进入玩一下。 从网上查得,连接CONSOLE接口用的是串口,只不过用RJ45水晶头插入而已。 山高路远,囊中羞涩,刚好手头上有一个文曲星的连接线,串口的。 凭自己半桶水的电子…

5月份Github上最热门的数据科学和机器学习项目

GitHub最近以数十亿美元的交易被微软收购。GitHub一直是开发人员之间协作的终极平台,我们已经看到数据科学和机器学习社区同样非常需要它,因此,我们希望GitHub能在微软的保护下继续发展下去。在本月排行中,上榜的项目有英特尔开源…

Blazor 中如何下载文件到浏览器

Blazor 中如何下载文件到浏览器目录一、前言二、方法一(导航跳转)三、方法二(下载后传出)(一) 使用 RestSharp 下载(二) 使用 BlazorDownloadFile 传出独立观察员 2021 年 3 月 28 日一、前言最近想给之前文章《下载中转加速器 VP…

荐书 | 5本数学科普让你不再“畏惧”数学,感受数学的内在美

最近,小木了解了许多关于数学的书籍,简直打开了小木数学新世界的大门。出版社寄了一些样书给小木,经过斟酌对比之后,推荐以下5本数学科普书给大家。01《数学简史》[中] 蔡天新 43.50提到数学,很多人的第一反应就是复杂…

ASP.NET Core依赖注入初识与思考

一、前言在上一篇中,我们讲述了什么是控制反转(IoC)以及通过哪些方式实现的。这其中,我们明白了,「控制反转(IoC)」 是一种软件设计的模式,指导我们设计出更优良,更具有松耦合的程序&#xff0c…