前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JWT-JSON Web令牌的深入介绍

JWT-JSON Web令牌的深入介绍

作者头像
ccf19881030
发布2020-06-29 11:01:13
2.3K0
发布2020-06-29 11:01:13
举报
文章被收录于专栏:ccf19881030的博客

JWT-JSON Web令牌的深入介绍

从桌面应用程序到Web应用程序或移动应用程序,身份验证是几乎所有应用程序中最重要的部分之一。 本教程是JWT(JSON Web令牌)的深入介绍,可帮助您了解:

  • 基于会话的身份验证与基于令牌的身份验证(为什么JWT诞生了)
  • JWT是如何工作的。
  • 如何创建JWT。
  • 我们如何保护我们的应用程序并验证JWT。

使用JWT的Spring Security概述: [按体系结构使用了 MySQL,Spring Security示例的Spring Boot JWT Auth[(https://bezkoder.com/spring-boot-jwt-mysql-spring-security-architecture/)

内容

  • 基于会话的身份验证和基于令牌的身份验证
  • JWT是如何工作的
  • 如何创建JWT
    • 标头
    • 有效载荷
    • 签名
    • 结合一切
  • JWT如何保护我们的数据
  • 服务端如何校验从客户端过来的JWT
  • 结论
  • 进一步阅读

基于会话的身份验证和基于令牌的身份验证

对于使用任何网站,移动应用程序或桌面应用程序……您几乎需要创建一个帐户,然后使用该帐户登录以访问该应用程序的功能。 我们称该行为为身份验证

那么,如何验证帐户? 首先,我们来看看过去流行的网站使用的一种简单方法:基于会话的身份验证

in-depth-introduction-jwt-session-based-authentication
in-depth-introduction-jwt-session-based-authentication

在上图中,当用户登录网站时,服务器将为该用户生成一个会话并将其存储(在内存或数据库中)。服务器还会为客户端返回一个SessionId,以将其保存在浏览器Cookie中。

服务器上的会话具有到期时间。在此时间之后,该会话已过期,用户必须重新登录才能创建另一个会话。

如果用户已登录并且会话尚未到期,则Cookie(包括SessionId)将始终与所有向服务器的HTTP请求一起使用。服务器将比较此SessionId与存储的会话以进行身份​​验证并返回相应的响应。

没关系。但是为什么我们需要基于令牌的身份验证? 答案是我们不仅有网站,而且那里有很多平台。

假设我们有一个与Session配合良好的网站。有一天,我们想为移动(本地应用程序)实现系统,并与当前的Web应用程序使用同一数据库。我们应该做什么?我们无法使用基于会话的身份验证对使用Native App的用户进行身份验证,因为这些类型没有Cookie。

我们是否应该构建另一个支持Native Apps的后端项目? 还是应该为Native App用户编写一个身份验证模块?

这就是基于令牌的身份验证诞生的原因。 使用此方法,服务器会将用户登录状态编码为JSON Web令牌(JWT),并将其发送给客户端。 如今,许多RESTful API都在使用它。 让我们转到下一部分,我们将知道它是如何工作的。

JWT是如何工作的

现在看下面的流程:

in-depth-introduction-jwt-token-based-authentication
in-depth-introduction-jwt-token-based-authentication

您会发现它很容易理解。 服务器没有创建会话,而是从用户登录数据生成了JWT,并将其发送给客户端。 客户端保存JWT,从现在开始,来自客户端的每个请求都应附加到该JWT(通常在标头处)。 服务器将验证JWT并返回响应。

要在客户端存储JWT,取决于您使用的平台: - 浏览器:Local Storage - IOS: Keychain - Android: SharedPreferences 这是基于令牌的身份验证流程的概述。 在下一节中,您将更深入地了解它。

如何创建JWT

首先,您应该了解JWT的三个重要部分:

  • 标头
  • 有效载荷
  • 签名

标头

标头回答了这个问题:我们将如何计算JWT? 现在来看一个标头示例,它是一个JSON对象,如下所示:

代码语言:javascript
复制
{
  "typ": "JWT",
  "alg": "HS256"
}

– typ是“ type”,表示此处的令牌类型是JWT。 – alg代表“算法”,它是一种用于生成令牌签名的哈希算法。 在上面的代码中,HS256是HMAC-SHA256 –使用密钥的算法。

有效载荷

有效负载可帮助我们回答:我们想在JWT中存储什么? 这是有效负载示例:

代码语言:javascript
复制
{
  "userId": "abcd12345ghijk",
  "username": "bezkoder",
  "email": "contact@bezkoder.com",
  // standard fields
  "iss": "zKoder, author of bezkoder.com",
  "iat": 1570238918,
  "exp": 1570238992
}

在上面的JSON对象中,我们存储3个用户字段:userId,username, email。 您可以保存所需的任何字段。

我们也有一些Standard Fields。 它们是可选的。

  • iss(Issuer):谁发行JWT
  • iat(发布于):JWT的发布时间:
  • exp(到期时间):JWT到期时间 我们可以在[https://en.wikipedia.org/wiki/JSON_Web_Token#Standard_fields](https://en.wikipedia.org/wiki/JSON_Web_Token#Standard_fields]查看更多的Standard Fields

签名

这部分是我们使用上面我告诉过您的哈希算法的地方。 查看下面获得签名的代码:

代码语言:javascript
复制
const data = Base64UrlEncode(header) + '.' + Base64UrlEncode(payload);
const hashedData = Hash(data, secret);
const signature = Base64UrlEncode(hashedData);

让我们解释一下。 –首先,我们对Header和Payload进行编码,并用点将它们连接起来。

代码语言:javascript
复制
data = '[encodedHeader].[encodedPayload]'

–接下来,我们使用带有秘钥字符串的Hash算法(在Header中定义)对数据进行哈希处理。 –最后,我们对哈希结果进行编码以获得签名

结合一切

在拥有Header,Payload,Signature之后,我们将它们组合成JWT标准结构:header.payload.signature。 以下代码将说明我们如何做到这一点。

代码语言:javascript
复制
const encodedHeader = base64urlEncode(header);
/* Result */
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"

const encodedPayload = base64urlEncode(payload);
/* Result */
"eyJ1c2VySWQiOiJhYmNkMTIzNDVnaGlqayIsInVzZXJuYW1lIjoiYmV6a29kZXIiLCJlbWFpbCI6ImNvbnRhY3RAYmV6a29kZXIuY29tIn0"

const data = encodedHeader + "." + encodedPayload;
const hashedData = Hash(data, secret);
const signature = base64urlEncode(hashedData);
/* Result */
"crrCKWNGay10ZYbzNG3e0hfLKbL7ktolT7GqjUMwi3k"

// header.payload.signature
const JWT = encodedHeader + "." + encodedPayload + "." + signature;
/* Result */
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJhYmNkMTIzNDVnaGlqayIsInVzZXJuYW1lIjoiYmV6a29kZXIiLCJlbWFpbCI6ImNvbnRhY3RAYmV6a29kZXIuY29tIn0.5IN4qmZTS3LEaXCisfJQhrSyhSPXEgM1ux-qXsGKacQ"

JWT如何保护我们的数据

代码语言:javascript
复制
JWT不保护您的数据

JWT完全不会隐藏,掩盖和保护数据。 您可以看到,生成JWT(标头,有效负载,签名)的过程仅对数据进行哈希处理,而不对数据进行加密。

JWT的目的是证明数据是由真实来源生成的。

那么,如果有中间人攻击可以获取JWT,然后解码用户信息怎么办? 是的,这是可能的,因此请始终确保您的应用程序具有HTTPS加密。

服务器如何从客户端验证JWT

在上一节中,我们使用Secret字符串创建签名。 此Secret字符串对于每个应用都是唯一的,并且必须安全地存储在服务器端。

从客户端接收JWT时,服务器获取签名,并验证签名是否已通过与上述相同的算法和Secret字符串正确地进行了哈希处理。 如果它与服务器的签名匹配,则JWT有效。

重要!

当发送给服务端时,有经验的程序猿仍然可以添加或编辑有效载荷信息。 在这种情况下我们该怎么办? 我们先存储令牌,然后再将其发送给客户端。 它可以确保客户端稍后发送的JWT有效。

此外,将用户的令牌保存在服务器上还将使系统的强制注销功能受益。

结论

永远不会有最佳的身份验证方法。 这取决于用例和实现方式。

但是,对于要在许多平台上扩展为大量用户的应用程序,首选JWT身份验证,因为令牌将存储在客户端。

祝您学习愉快,再见!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/06/25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JWT-JSON Web令牌的深入介绍
    • 内容
      • 基于会话的身份验证和基于令牌的身份验证
        • JWT是如何工作的
          • 如何创建JWT
            • 标头
              • 有效载荷
                • 签名
                  • 结合一切
                    • JWT如何保护我们的数据
                      • 服务器如何从客户端验证JWT
                        • 结论
                        相关产品与服务
                        对象存储
                        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档