无状态JSON Web令牌中存储的内容

时间:2018-10-21 23:58:25

标签: javascript security authentication cookies jwt

最近,我一直在阅读JWT,并且我对它们的制造方式以及如何将其用于身份验证有了相当不错的了解。

如果我理解正确,当我需要多个Web服务(API),而使用该应用程序的每种类型的设备(Web,移动设备等)都需要一个API时,有状态应用程序就会面临挑战。然后,Web服务必须以某种方式同步会话状态,这很困难。

相反,我们将状态客户端(最好在cookie中)存储在经过加密和签名的JWT中。

到目前为止我是否正确理解了?

然后,我的主要问题:JWT中到底存储了什么,比如说一个在线商店?它会完全取代存储在数据库中的所有用户信息吗?因此,配置文件信息,图像,购物车,已保存的内容(文章,存储库等,如果适用)等等。保存在JWT中的所有这些内容以及所有其他可想象的内容(一个用户到另一个用户)是否不同?

总而言之,我试图弄清JWT用例中的无状态是什么意思?我们是否将所有用户信息存储在令牌中?

1 个答案:

答案 0 :(得分:3)

  

[..]当我需要多个Web服务(API)时,每种使用该应用程序的设备(Web,移动设备等)都需要一个。

我认为按客户端类型分开服务器后端的体系结构很差。理想情况下,后端将为Web客户端和移动客户端(以及任何其他客户端)提供完全相同的API。否则,每个受支持的功能都会有大量的重复工作和开销。

因此,让我们大致上将注意力集中在拥有几个服务器的情况下。亚马逊(Amazon.com)认为,任何严肃的大型网站所拥有的不仅仅是一个服务器来为其网站服务。它们具有单独的服务器实例,可以根据需求的增加自动上线,而随着流量的下降而又脱机。负载平衡器根据需要将流量定向到各个服务器。

在这种情况下,尤其是在购物网站中,您有几种处理状态的方法,每种方法都有其优点和缺点:

  1. 使用粘性会话,这意味着Web服务器是有状态的并存储会话信息,并且负载平衡器知道已使用的cookie,并将流量从同一客户端定向到同一服务器,因此仅一台服务器需要保持会话信息。这使服务器的实现相对简单,但在操作上有某些缺点:

    • 负载均衡器需要能够处理粘性会话。
    • 客户端存在时服务器需要保持在线状态,否则会话信息将被丢弃。
    • 如果客户端在地理位置上转移到另一个负载均衡器,则他们可能会与会话断开连接。
  2. 使用共享的会话存储后端,因此每个服务器基本上共享相同的信息。这消除了使用粘性会话的弊端,但显然重新引入了单个共享资源的瓶颈,并影响了可伸缩性。使用良好的缓存策略可以在某种程度上缓解这种情况,但是写入共享存储仍然需要庞大的后端。

  3. 使所有内容保持无状态,并在客户端上进行尽可能多的处理。客户记住自己的历史和/或购物篮内容。服务器所需要做的就是提供产品信息,该信息不是特定于客户端的,因此具有很高的可扩展性。当然,当需要结帐或执行其他特定于客户端的操作时,服务器将需要执行特定于客户端的操作并使用某种类型的会话,但是与随意浏览相比,这只是流量的一小部分还有很多问题。

    在这种情况下,JWT用来承载需要验证的信息,例如用户身份,即身份验证。为了进行身份验证,您可以:

    1. 让客户端对每个请求进行身份验证,即,对每个请求发送其用户名和密码。这显然不是一个好主意,因为您不想不断地来回发送密码。它还将每次都需要查询后端的中央数据库,这再次破坏了可伸缩性。
    2. 为用户提供某种形式的令牌,以对其进行身份验证。此处的缺点是需要共享令牌存储,请参见上面的#2。


    JWT可以让您同时拥有两种方式:用户基本上在每个请求中都声明他们是用户X (无需发送密码),并且因为JWT是由签名服务器,它允许服务器实际信任该声明。每个服务器都可以独立地验证签名,因此可以独立地对每个请求信任声明,从而保持无状态,并且不需要任何类型的共享存储。

    在JWT中存储信息的一个缺点是它们仅存在于一个客户端上,因此一旦用户移至另一个客户端或清除cookie,您在那里存储的任何信息将不复存在。因此仅使用JWT便无法在用户帐户的设备之间同步购物篮。

在实践中,您可能将至少使用两种,可能同时使用所有三种方法。您将在某处有一些 个共享存储空间来存储帐户信息(包括购物篮),但是通过 将该存储空间缓存起来,可以尽可能减少与该存储空间联系的需要。粘性会话和/或JWT中的数据。通过JWT进行无状态身份验证是不费吹灰之力的。对于其他所有方面,您都需要在分配共享存储上的负载,任何共享/缓存状态的最新状态以及最终用户体验之间做出正确的权衡。