代码之家  ›  专栏  ›  技术社区  ›  Magnus

存储在无状态json web令牌中的内容

  •  2
  • Magnus  · 技术社区  · 6 年前

    我最近一直在阅读jwt,我觉得我对它们是如何制作的以及如何用于身份验证有相当好的把握。

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

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

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

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

    最后,我试图了解jwt用例中无状态的含义是什么?我们是否将所有用户信息存储在令牌中?

    1 回复  |  直到 6 年前
        1
  •  3
  •   deceze    6 年前

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

    我认为按照客户机的类型来分离服务器后端是不好的架构。理想情况下,后端将为web客户端和移动客户端(以及任何其他客户端)提供完全相同的api。否则,对于每个支持的特性,都会有巨大的重复和开销。

    所以,让我们把注意力集中在 多台服务器 . 任何一个严肃的大型网站,比如amazon.com,都有不止一个服务于他们网站的服务器。它们有单独的服务器实例,当需求增加时自动联机,而当流量减少时又掉线。负载平衡器根据需要将通信量定向到各个服务器。

    在这种情况下,特别是购物网站,你有几种方法来处理状态,每种方法都有一定的利弊:

    1. 使用粘滞会话,这意味着web服务器是有状态的并存储会话信息,负载平衡器知道使用的cookie,并将流量从同一个客户端引导到同一个服务器,因此只有一个服务器需要保留会话信息。这使得服务器实现相对简单,但在操作上有一些缺点:

      • 负载平衡器需要能够处理粘性会话。
      • 客户端存在时,服务器需要保持联机,否则会话信息将被丢弃。
      • 如果客户端在地理位置上移动到另一个负载平衡器,它们可能会与会话断开连接。
    2. 使用共享会话存储后端,因此每个服务器实质上共享相同的信息。这消除了使用粘性会话的缺点,但显然会重新引入单个共享资源的瓶颈,并影响可伸缩性。这可以通过使用良好的缓存策略在一定程度上减轻,但写入共享存储仍然需要一个巨大的后端。

    3. 保持一切无状态,并尽可能在客户机上处理。客户记得自己的历史和/或篮子内容。服务器需要做的只是提供产品信息,这是非特定于客户机的,因此具有极大的可伸缩性。当然,当需要签出或执行其他特定于客户机的操作时,服务器需要执行特定于客户机的操作,并使用某种会话,但与随意浏览相比,这只是流量的一小部分,问题要小得多。

      在这种情况下,jwts提供需要验证的信息,比如 用户是谁, 即认证。出于身份验证目的,您可以:

      1. 让客户机对每个请求进行身份验证,即在每个请求中发送他们的用户名和密码。这显然是个坏主意,因为你不想经常来回发送密码。它还需要每次都对后端的中心数据库进行查询,这再次破坏了可伸缩性。
      2. 给用户一个某种令牌来验证他们。这里的缺点是需要共享令牌存储,请参见上面的2。


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

      在jwts中存储信息的一个缺点是它们只存在于一个客户机上,因此,一旦用户移动到另一个客户机或清除cookies,您存储在那里的任何信息都将停止存在;因此,仅使用jwts是不可能在用户帐户的设备之间同步购物篮的。

    实际上,您可能会同时使用至少两种方法,可能是全部三种方法。你会有 一些 在某个地方共享存储帐户信息(包括购物篮),但通过 在粘性会话和/或jwt中缓存数据。通过jwts进行无状态身份验证是一件很简单的事情。对于其他一切,您可以决定在向共享存储分配负载、任何共享/缓存状态的最新程度以及最终用户体验之间的正确权衡。