【问题标题】:Is "logout" useless on a REST API?“注销”在 REST API 上没用吗?
【发布时间】:2016-07-17 14:27:19
【问题描述】:

考虑到,根据定义,REST API 是无状态的:“注销”操作是否无用?

我的意思是,我正在使用加密的 JWT 创建一个 REST API。每个令牌都有一个过期时间,比如说 60 分钟。如果我将 API 生成的最后一个令牌保存在数据库表中,“注销”将完成从有效令牌表中删除它们。但是,如果我这样做,我知道 API 将不再是无状态的,对吧?

所以,我知道我不应该这样做。我在想的唯一解决方案是将 JWT 过期时间缩短到 5 分钟,不要实施“注销”操作,让令牌过期。

这是正确的方法吗?

【问题讨论】:

    标签: rest logout jwt api-design


    【解决方案1】:

    我认为你的 API 已经是有状态的,仅仅因为你有一个令牌。我也不会太在意 REST 纯度,这意味着一切必须在地狱或高水位时都是无状态的。

    简单地说,如果您的应用程序需要登录,那么您需要一种退出方式。你不能实现一个短暂的过期,因为这对于 API 的消费者来说是一个非常烦人的体验。而且你不能只是没有注销,因为那是一个潜在的安全漏洞。

    我有一个我支持的类似 REST API,并且我实现了一个注销端点,它是一个 DELETE 调用。它只是删除服务器端的令牌信息并清除登录用户的任何类型的身份验证。

    TL;DR

    不,注销在 REST API 中并非毫无用处。事实上,对于需要身份验证的 API,它或多或少是必需的。

    【讨论】:

    • 如果您必须“删除登录用户的令牌信息和任何其他类型的身份验证...”,您的实现似乎没有使用 JWT。
    【解决方案2】:

    自动令牌到期是与显式“注销”机制不同的问题,因此,无论您的 API 是否为 ReSTful,它们都是完全有效的操作。

    当用户注销时,他们有意识地决定使其访问令牌无效 - 例如,如果他们正在使用公共计算机或临时借用他人的设备。

    自动过期用于确保用户必须以某种方式定期重新验证。这有利于服务器端的安全性。

    访问令牌不是关于在客户端和服务器之间共享会话状态 - 完全有可能在没有共享状态的情况下实现访问令牌系统,并且令牌本身不实现会话状态,它仅用于验证用户是谁自称。因此,访问令牌实际上与 API 的状态无关。

    【讨论】:

      【解决方案3】:

      我的意思是,我正在使用加密的 JWT 创建一个 REST API

      JSON Web 令牌 (JWT) 令牌将有关授权的所有数据编码到令牌本身。这种方法最重要的优点是您根本不需要后端存储来存储令牌。一个缺点是您不能轻易地撤销访问令牌,因此它们通常被授予短期到期,并且撤销是在刷新令牌处处理的。另一个缺点是,如果您在其中存储大量用户凭证信息,令牌可能会变得非常大。所以如果:

      如果我将 API 生成的最后一个令牌保存在数据库表中, “注销”将完成从有效表中删除它们 代币

      那么您将失去使用 JWT 最重要的优势,并且仍然有所有这些缺点,这在我看来是不合理的。

      所以,我知道我不应该这样做。我唯一的解决方案 想法是让 JWT 过期时间更短,到 5 分钟,不要 实现“注销”操作,让令牌过期。

      这是正确的方法吗?

      在我看来,如果您打算使用 JWT,是的!最好依靠令牌过期。有关此方法的更多详细信息,您可以查看this question

      “注销”在 REST API 上没有用吗?

      不管您使用的是 JWT 还是与计算机科学中任何其他体面的问题类似,答案都是 It DependsStatelessness 最重要的优势是您的 API 将更具可扩展性。如果您选择此路径,您的 API 上的每个请求可能都应该经过身份验证,因为您可能需要在后端存储中搜索给定的令牌或解码 JWT 令牌。因此,在这种情况下,您可能会在单个节点上花费一些性能成本,但从整体上看,您仍然具有可伸缩性。我想我想说的是,如果你不需要那种可扩展性,你最好选择 Stateful 方法。否则,纯 REST 原则是可行的方法。

      【讨论】:

      • 可扩展性是关键......现在依靠过期时间看起来是正确的道路。
      • 然后我建议阅读有关使用 JWT 令牌的最佳实践的更多信息。链接的问题在这方面非常有用...玩得开心
      • 谢谢,您对为什么使用 JWT 提出了非常明确的观点
      【解决方案4】:

      您可以生成一个已过期的新令牌,即过期时间为 1 秒。并将其传递给用户。任何即将到来的请求都将无效。虽然这不是最佳解决方案..

      【讨论】:

        【解决方案5】:

        我认为这取决于您希望应用程序的行为,以及您需要它的安全程度。您真的需要使令牌无效吗? 例如,您可以从前端(浏览器或应用程序)中删除您的令牌。理论上,它是唯一存储该特定令牌的地方。但是,如果令牌被泄露,它在过期之前仍然有效。

        如果你真的需要在服务器端使其失效,一种常见的方法是使用令牌创建一个黑名单,并不时清除过期的条目。

        但是,如果您需要您的应用程序为每个用户只接受一个令牌,例如在银行应用程序中您一次只能登录一台设备,该怎么办?为此,黑名单将无法完成这项工作,因此您需要为每个用户存储一个令牌并检查传递的令牌是否相同。在注销时,您只需清除该唯一条目。或者您可以只使用会话。

        所以,它不是没用的,它只是取决于你的应用程序。

        【讨论】:

          【解决方案6】:

          令牌的过期时间很短,我认为对于大多数应用程序来说,在注销时从客户端删除令牌将是一个很好的解决方案。更多的东西将依赖于服务器并且不再是无状态的。

          【讨论】:

            【解决方案7】:

            这里最好的解决方案是从用户那里删除令牌。 所以通常当你登录时,你会从服务器取回一个令牌并将其存储在浏览器的 localStorage 或 sessionStorage 中(取决于关闭选项卡后想要登录的用户),然后从那里发送令牌您对 api 发出的任何请求的标头。

            然后如果用户退出,你甚至不联系api(你不向你的服务器发出任何请求),你只需清除sessionStorage或localStorage,使用命令@ 987654321@ 或 sessionStorage.clear() ,然后如果用户想要发送更多请求,他必须再次登录才能获得另一个令牌。

            这种方法的一个缺点是,如果病毒(例如)从本地或会话存储中获取令牌在用户注销之前,它仍然会能够像您一样发送请求,因为令牌仍然有效。 一种解决方案是在数据库中创建 token blacklist,如果用户注销,则将 token 存储在那里,直到 token 过期时间。但是,每次用户请求某些东西时,都必须查询数据库以检查他的令牌是否被列入黑名单,从而延长流程并使您的 API 有状态。

            【讨论】:

              猜你喜欢
              • 2015-06-28
              • 2020-03-19
              • 2014-12-22
              • 1970-01-01
              • 2020-10-21
              • 2011-05-08
              • 1970-01-01
              • 1970-01-01
              • 2017-06-18
              相关资源
              最近更新 更多