什么是JWT

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

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

应该在什么时候使用JWT?

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

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

在计算机科学与电信领域,负载(英语:Payload)是数据传输中所欲传输的实际信息,通常也被称作实际数据或者数据体。信头与元数据,或称为开销数据,仅用于辅助数据传输。在计算机病毒或电脑蠕虫领域中,负载指的是进行有害操作的部分,例如:数据销毁、发送垃圾邮件等。

JWT与Session Id比较

小型Web应用程序

1) Session Id实现

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

Session Id描述了用于识别HTTP会话的统一资源标识符。会话标识UIS允许在有限域内链接HTTP交易。这为商业服务器对人口数据收集的需求和用户的隐私问题提供了平衡。此外,会话识别UIS可用作高安全性认证机制的一部分,以防止重播攻击。

Cookie,有时也用其复数形式Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

2) JWT实现

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

网络存储(Web Local Storage)可以被看作为改进的Cookie,提供更大的存储容量(在谷歌浏览器2.5 MB每网域。在Mozilla FirefoxOpera中为5 MB每网域。在Internet Explorer中则为10 MB 每存储区域)和更好的编程接口。

Cookie可以被客户端和服务器访问,但网络存储只限被客户端脚本(Client-SideScripts,例如JavaScript)控制。网络存储的资料并不会在每个HTTP请求下发送到服务器,网络服务器亦不能直接把资料直接写入到网络存储,但是当然可以发出读取和写入请求。

3) 总结

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

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

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

1) Session Id实现

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

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

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

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

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

  • 需要大量的RAM、CPU、存储来跟踪所有这些会话和平稳地处理请求
  • 需要维护缓存,以确保没有幽灵会话或无效会话
  • 万一某台服务器崩溃,所有未与缓存同步的会话都会丢失
  • 使用户无效更复杂
  • 托管成本高

2) JWT实现

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

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

3) 总结

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

JWT和Session Id的区别总结

让我们来快速总结一下JWTSession Id的区别

1) JWT

  • 服务器上不保存任何东西,JWT存储于客户端中
  • 由服务器加密和签名
  • Token包含用户的所有信息
  • 所有信息都存储于Token本身中
  • 易于缩放

2) Session Id

  • Session Id保存于服务器和客户端中
  • 加密并签名
  • Session Id是对用户的引用
  • 服务器需要查找用户并进行必要的检查
  • 难以缩放

JWT结构

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

  • Header(标头)
  • Payload(有效负载)
  • Signature(签名)

因此,JWT通常如下所示:

xxxxxx.yyyyyyy.zzzzzzzz

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

Header

Header通常由两部分组成:

  • Token的类型,这里是JWT
  • 使用的签名算法,比如HMACSHA256RSA

例如:

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

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

Payload(Data)

Token的第二部分是有效负载,其中包含Claims(声明),Claims是有关实体(通常是用户)和其他数据的声明。

有三种类型的Claimsregisteredpublicprivate claims

  • Registered Claims:这是一组非强制性的但建议使用的预定义Claims,以提供一组有用的、可互操作的Claims。其中包含:iss(issuer,签发者)、exp(expirationtime,过期时间)、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的第二部分。

除非将其加密,否则请不要将机密信息放入JWTPayloadHeader元素中。

签名

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

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

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

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

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

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

1) 签名方式

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

  • 一个Secret(使用HMAC算法)
  • 一个公钥/私钥对(使用RSAECDSA

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

参考

温故知新,.Net Core遇见JWT(JSON Web Token)授权机制方案的更多相关文章

  1. Java JWT: JSON Web Token

    Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand libr ...

  2. JWT(JSON Web Token) 【转载】

    JWT(JSON Web Token) 什么叫JWTJSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. 一般来说,互联网用户认证是这样子的. 1.用户向服务器发送用户名和密码. ...

  3. [更新]一份包含: 采用RSA JWT(Json Web Token, RSA加密)的OAUTH2.0,HTTP BASIC,本地数据库验证,Windows域验证,单点登录的Spring Security配置文件

    没有任何注释,表怪我(¬_¬) 更新: 2016.05.29: 将AuthorizationServer和ResourceServer分开配置 2016.05.29: Token获取采用Http Ba ...

  4. 如何在SpringBoot中集成JWT(JSON Web Token)鉴权

    这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...

  5. ( 转 ) 什么是 JWT -- JSON WEB TOKEN

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

  6. 关于JWT(Json Web Token)的思考及使用心得

    什么是JWT? JWT(Json Web Token)是一个开放的数据交换验证标准rfc7519(php 后端实现JWT认证方法一般用来做轻量级的API鉴权.由于许多API接口设计是遵循无状态的(比如 ...

  7. 什么是JWT(Json Web Token)

    什么是 JWT (Json Web Token) 用户认证是计算机安全领域一个永恒的热点话题. JWT 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该to ...

  8. API安全验证之JWT(JSON WEB TOKEN) OLCMS

    假如www.olcms.com/getUserInfo获取用户信息,你怎么知道当前用户是谁?有人说登陆时候我把他UID写入session了,如果是API接口,没有session怎么办,那么就需要把UI ...

  9. 5分钟搞懂:JWT(Json Web Token)

    https://www.qikegu.com/easy-understanding/892 JWT 基于token的用户认证原理:让用户输入账号和密码,认证通过后获得一个token(令牌),在toke ...

随机推荐

  1. 【打印机】无法连接 fail to connect to server cups 服务器错误 打印机

       打印机     fail to connect to server cups 服务器错误兆芯 打印机 连不上了####message可知 服务fail## systemd: cups.servi ...

  2. vim使用基础

    vi/vim编辑器使用 前言 There is an old joke about a visitor to New York City asking a passerby for direction ...

  3. Zabbix 架构

    Zabbix 架构 1.Zabbix Server Zabblx server是agent程序报告系统可用性.系统完整性和统计数据的核心组件,是所有配置信息.统计信息和操作数据的核心存储器. 2.Za ...

  4. 8.5-7 mkfs、dumpe2fs、resize2fs

    8.5 mkfs:创建Linux文件系统     mkfs命令用于在指定的设备(或硬盘分区等)上创建格式化并创建文件系统,fdisk和parted等分区工具相当于建房的人,把房子(硬盘),分成几居室( ...

  5. WIFF SD卡

    https://detail.tmall.com/item.htm?spm=a230r.1.14.1.2d4d6923Fq3Hgx&id=36945441834&cm_id=14010 ...

  6. Python数模笔记-StatsModels 统计回归(4)可视化

    1.如何认识可视化? 图形总是比数据更加醒目.直观.解决统计回归问题,无论在分析问题的过程中,还是在结果的呈现和发表时,都需要可视化工具的帮助和支持. 需要指出的是,虽然不同绘图工具包的功能.效果会有 ...

  7. unity UGUI填坑 之 HorizontalLayoutGroup 和 ContentSizeFitter配合使用

    今天在项目中遇到一个问题,我们的ui过来找我,问为什么Content里的Item显示的不完全 花了半个小时看了一下,发现个小小的坑,记录一下 这些属性是用来实现,Content下的Item的偏移和间隔 ...

  8. 深入剖析 MySQL 自增锁

    之前的文章把 InnoDB 中的所有的锁都介绍了一下,包括意向锁.记录锁...自增锁巴拉巴拉的.但是后面我自己回过头去看的时候发现,对自增锁的介绍居然才短短的一段. 其实自增锁(AUTO-INC Lo ...

  9. 记go中一次http超时引发的事故

    记一次http超时引发的事故 前言 分析下具体的代码实现 服务设置超时 客户端设置超时 http.client context http.Transport 问题 总结 参考 记一次http超时引发的 ...

  10. openresty 学习笔记一:环境安装

    openresty 学习笔记一:环境安装 openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭 ...