在REST API上“注销”无用吗?

时间:2016-03-29 20:19:43

标签: rest logout jwt api-design

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

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

所以,我明白我不应该这样做。我正在考虑的唯一解决方案是将JWT到期时间缩短到5分钟,不执行“注销”操作并让令牌过期。

这是正确的方法吗?

7 个答案:

答案 0 :(得分:5)

  

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

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

  

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

那么你将失去使用JWT的最重要的优势,并且仍然具有所有这些缺点,这对我来说似乎是不合理的。

  

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

     

这是正确的方法吗?

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

  

REST API上的“注销”无效吗?

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

答案 1 :(得分:1)

我认为你的API已经是有状态的,只是因为你有一个令牌。我也不会太依赖REST的纯度,这意味着所有都是无国籍的地狱或高水。

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

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

TL; DR

不,注销在REST API中没用。实际上,对于需要身份验证的API,它或多或少是必需的。

答案 2 :(得分:1)

自动令牌到期是明确"退出"的另一个问题。机制,因此,无论您的API是否为ReSTful,它们都是完全有效的操作。

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

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

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

答案 3 :(得分:1)

我认为这取决于应用程序所需的行为以及所需的安全性。您真的需要使令牌无效吗? 例如,您可以只从前端(浏览器或应用程序)中删除令牌。从理论上讲,它是唯一存储该特定令牌的地方。但是,如果令牌遭到破坏,它将一直有效,直到令牌过期。

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

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

所以,它并不是没有用的,它取决于您的应用程序。

答案 4 :(得分:0)

由于令牌的有效期限很短,我认为对于大多数应用程序来说,注销后从客户端删除令牌是一个很好的解决方案。一切都会依赖服务器,而不再是无状态的。

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:-1)

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