温故知新,.Net Core遇见JWT(JSON Web Token)授权机制方案

什么是JWTJWT (JSON Web Token) 是一个开放标准,它定义了一种以紧凑和自包含的方法,用于在双方之间安全地传输编码为JSON对象的信息。因此,简单来说,它是JSON格式的加密字符串,其中包含敏感信息,它使我们能够...

什么是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作匹配,以验证用户是否被授权。

2) JWT实现

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

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将仍然有效,因为所有服务器上的加密机制是一样的。

参考

  • Intro to JWT - Step by Step
  • JWT 介绍 - Step by Step
  • 负载 (Payload)
  • Role-based and Claims-based Authorization in ASP.NET Core using Policies - Hands on
  • role-policy-authorization-sample

本文标题为:温故知新,.Net Core遇见JWT(JSON Web Token)授权机制方案

基础教程推荐