5步轻松理解JSON Web令牌(JWT)

在本文中,将解释JSON Web令牌(JWT)的基本概念,以及使用它们的原因。JWT是确保应用程序中的信任和安全性的重要部分。JWT允许以安全的方式表示声明,例如用户数据。

为了解释JWT是如何工作的,让我们从一个抽象的定义开始。

JSON Web令牌(JWT)是一个JSON对象,它在 RFC 7519 中定义为在双方之间表示一组信息的安全方法。令牌由头、有效负载和签名组成。

简而言之,JWT就是一个字符串,格式如下:

header.payload.signature

应该注意,双引号字符串实际上被认为是一个有效的JSON对象。

为了展示JWT是如何以及为什么被实际使用的,我们将使用一个简单的3实体示例(参见下图)。本例中的实体是用户、应用程序服务器和身份验证服务器。身份验证服务器将向用户提供JWT。使用JWT,用户可以安全地与应用程序通信。
image

在本例中,用户首先使用身份验证服务器的登录系统(例如用户名和密码、Facebook登录、谷歌登录等)登录身份验证服务器。然后,身份验证服务器创建JWT并将其发送给用户。当用户对应用程序进行API调用时,用户将JWT与API调用一起传递。在这一步中,应用服务器将验证传入的由身份验证服务器创建的JWT(稍后将更详细地解释验证过程)。因此,当用户使用附加的JWT进行API调用时,应用程序可以使用JWT来验证API调用来自经过身份验证的用户。

现在,JWT本身,以及它是如何构建和验证的,将被更深入地研究。

步骤一 创建头

JWT的头组件包含关于如何计算JWT签名的信息。报头是一个JSON对象,格式如下:

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

在这个JSON中,“typ”键的值指定对象是JWT,而“alg”键的值指定使用哪种散列算法来创建JWT签名组件。在我们的示例中,我们使用HMAC-SHA256算法(一种使用密钥的散列算法)来计算签名(在步骤3中有更详细的讨论)。

步骤二 创建负载

JWT的有效负载组件是存储在JWT内部的数据(该数据也称为JWT的“声明”)。在我们的示例中,身份验证服务器创建一个JWT,其中存储有用户信息,特别是用户ID。

{
    "userId": "b08f86af-35da-48f2-8fab-cef3904660bd"
}

在示例中,我们只向有效载荷提交了一个声明。你可以根据需要配置任意多的声明。JWT有效载荷有几种不同的标准声明,比如“iss”发布者、“sub”subject和“exp”过期时间。在创建JWT时,这些字段可能很有用,但是它们是可选的。有关JWT标准字段的更详细列表,请参阅JWT的wikipedia页面。

请记住,数据的大小将影响JWT的总体大小,这通常不是问题,但是过大的JWT可能会对性能产生负面影响并导致延迟。

步骤三 创建签名

使用以下伪代码计算签名:

// signature algorithm
data = base64urlEncode( header ) +.+ base64urlEncode( payload )
hashedData = hash( data, secret )
signature = base64urlEncode( hashedData )

这个算法所做的是base64url对步骤1和步骤2中创建的头和有效负载进行编码。然后,算法用连接符(.)将运算后的编码字符串连接起来。在我们的伪代码中,这个连接的字符串被赋值给 data。字符串data使用JWT头中指定的哈希算法对密钥进行哈希。计算出的哈希数据被赋值给hashedData。然后对这个散列数据进行base64url编码,以生成JWT签名。

在我们的例子中,头部和有效载荷都是base64url编码的:

// header
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
// payload
eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ

然后,在连接的编码头和编码负载上应用带有密钥的指定签名算法,得到签名所需的散列数据。在我们的示例中,这意味着在数据字符串上应用HS256算法,将密钥设置为字符串“secret”,以获得hashedData字符串。之后,通过base64url编码hashedData字符串,得到如下JWT签名:

// signature
-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

步骤四 将所有三个JWT组件放在一起

现在我们已经创建了所有三个组件,可以创建JWT了。记住JWT的header.payload.signature结构,我们只需要将组件组合起来,并用句点(.)分隔它们。我们使用头部和有效负载的base64url编码版本,以及我们在步骤3中得到的签名。

// JWT Token
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ.-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

您可以在JWT.io上通过浏览器尝试创建自己的JWT。

回到我们的示例,身份验证服务器现在可以将此JWT发送给用户。

JWT如何保护我们的数据?

重要的是要理解使用JWT的目的不是以任何方式隐藏数据。使用JWT的原因是为了证明发送的数据实际上是由一个真实的源创建的。如上面的步骤所示,JWT中的数据是编码签名的,而不是加密的。编码数据的目的是转换数据的结构。签名数据允许数据接收器验证数据源的真实性。因此,编码和签名数据并不保护数据。另一方面,加密的主要目的是保护数据和防止未经授权的访问。有关编码和加密之间的区别的更详细解释,以及关于哈希如何工作的更多信息,请参阅本文

由于JWT只签名和编码,JWT不加密,因此JWT不保证敏感数据的任何安全性。

步骤五 验证JWT

在我们的简单3实体示例中,我们使用的JWT由HS256算法签名,其中只有身份验证服务器和应用服务器知道密钥。当应用程序设置其身份验证过程时,应用程序服务器从身份验证服务器接收密钥。由于应用程序知道密钥,所以当用户对应用程序进行JWT附加API调用时,应用程序可以执行与JWT上步骤3中相同的签名算法。然后,应用程序可以验证从自己的哈希操作获得的签名是否与JWT本身的签名匹配(即它与身份验证服务器创建的JWT签名匹配)。如果签名匹配,则意味着JWT是有效的,这表明API调用来自一个真实的源。否则,如果签名不匹配,则意味着接收到的JWT无效,这可能是对应用程序的潜在攻击的一个指示器。因此,通过验证JWT,应用程序在自己和用户之间添加了一层信任。

总结

我们讨论了JWT是什么,如何创建和验证它们,以及如何使用它们来确保应用程序及其用户之间的信任。这是理解JWT的基本原理以及它们为何有用的起点。JWT只是确保应用程序中的信任和安全性的一小部分。

原文链接:5 Easy Steps to Understanding JSON Web Tokens (JWT)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值