REST API安全性存储令牌vs JWT vs OAuth


104

我仍在尝试寻找最佳的安全解决方案来保护REST API,因为移动应用程序和API的数量每天都在增加。

我尝试了不同的身份验证方式,但是仍然存在一些误解,因此我需要经验丰富的人的建议。

让我说说,我如何理解所有这些东西。如果我理解不正确,请告诉我。

就REST API和WEB而言,它都是无状态的,我们需要在每个请求中发送一些auth数据(cookie,令牌...)。我知道三种用于验证用户身份的广泛使用的机制

  1. 使用HTTPS的令牌。我已经使用这种方法很多次,对于HTTPS来说已经足够了。如果用户提供正确的密码和登录名,他将收到令牌作为响应,并将其用于其他请求。令牌由服务器生成并存储,例如存储在单独的表中或存储用户信息的表中。因此,对于每个请求服务器,检查用户是否具有令牌,并且该令牌与数据库中的令牌相同。一切都非常简单。

  2. JWT令牌。该令牌是自描述的,它包含有关令牌本身的所有必要信息,用户无法更改(例如到期日期)或任何其他声明,因为该令牌是由服务器使用secret关键字生成(签名)的。这也很清楚。但是对我个人来说,一个大问题是如何使令牌无效。

  3. OAuth2。我不明白为什么直接在服务器和客户端之间建立通信时应使用这种方法。据我了解,OAuth服务器用于发布具有受限范围的令牌,以允许其他应用程序访问用户信息而无需存储密码和登录名。对于社交网络而言,这是一个很好的解决方案,当用户想要在某个页面上进行注册时,服务器可以请求权限以获取用户信息(例如,从Twitter或Facebook获取信息),并使用用户数据等填充注册字段。

考虑将移动客户端用于在线商店。

第一个问题,我应该比第一类令牌更喜欢JWT吗?就我需要在移动客户端上登录/注销用户而言,我需要将令牌存储在某个地方,或者在JWT的情况下,令牌应该在注销时失效。使用不同的方法来使令牌无效,其中之一是创建无效的令牌列表(黑名单)。嗯 表/文件的大小比令牌存储在表中并与用户相关联并且在注销时被删除时要大得多。

那么,JWT令牌的好处是什么?

关于OAuth的第二个问题,如果与服务器直接通信,应该使用它吗?客户端和服务器之间仅发出令牌的另一层的目的是什么,但是通信将不是与oauth服务器,而是与主服务器。据我了解,OAuth服务器仅负责授予第三方应用访问用户私人信息的权限(令牌)。但是我的移动客户端应用程序不是第三方。


谢谢,我最近很奇怪。我使用会话管理(Beaker),一个小时后删除了会话令牌。Oauth似乎不合适。
JasTonAChair

Answers:


86

考虑第一种情况。每个客户都会获得一个随机ID,该ID可以持续到会话期间-如果您愿意,可以是几天。然后,将与该会话相关的信息存储在服务器端。它可以在文件或数据库中。假设您通过Cookie传递ID,但可以使用URL或HTTP标头。

会话ID / Cookie

优点:

  • 易于编码客户端和服务器。
  • 有人注销时很容易破坏会话。

缺点:

  • 服务器端需要定期删除客户端未注销的过期会话。
  • 每个HTTP请求都需要查找数据存储。
  • 随着更多用户拥有活动会话,存储需求也随之增长。
  • 如果有多个前端HTTP服务器,则所有服务器都需要访问存储的会话数据。与将其存储在一台服务器上相比,这可能需要更多的工作。更大的问题是数据存储成为单点故障,并且可能成为瓶颈。

JSON Web令牌(JWT)

在第二种情况下,数据存储在传递的JWT中,而不是存储在服务器上。

优点:

  • 服务器端存储问题已解决。
  • 客户端代码很简单。

缺点:

  • JWT的大小可能大于会话ID。由于它包含在每个HTTP请求中,因此可能会影响网络性能。
  • 客户端可以读取存储在JWT中的数据。这可能是一个问题。
  • 服务器端需要代码来生成,验证和读取JWT。这并不难,但是有一些学习曲线,安全性取决于它。

    任何获得签名密钥副本的人都可以创建JWT。您可能不知道什么时候发生。

    一些库中有一个错误,它接受任何用“ none”算法签名的JWT,因此任何人都可以创建服务器可以信任的JWT。

  • 为了在JWT过期之前撤消JWT,您需要使用撤消列表。这使您回到试图避免的服务器端存储问题。

OAuth

OAuth通常用于身份验证(即身份),但也可以用于共享其他数据,例如用户已购买并有权下载的内容列表。它还可以用于授予访问权限以写入第三方存储的数据。您可以使用OAuth对用户进行身份验证,然后将服务器端存储或JWT用于会话数据。

优点:

  • 用户无需注册或重置密码的密码。
  • 没有代码发送带有验证链接的电子邮件,然后验证地址。
  • 用户无需学习/写下其他用户名和密码。

缺点:

  • 您依赖第三方才能使用户使用您的服务。如果他们的服务中断或中止服务,则您需要找出其他解决方案。例如:如果用户的身份从“ foo@a.com”更改为“ bar@b.com”,如何迁移用户的帐户数据?
  • 通常,您必须为每个提供程序编写代码。例如Google,Facebook,Twitter。
  • 您或您的用户可能有隐私问题。提供者知道哪些用户使用您的服务。
  • 您信任提供者。提供者可以将对一个用户有效的令牌发行给其他人。这可能出于合法目的。

  • 会话ID和JWT都可以被多个用户复制和使用。您可以将客户端IP地址存储在JWT中并对其进行验证,但这可以防止客户端从Wi-Fi漫游到蜂窝网络。

要添加到您的答案中,当用户希望使用其公司帐户进行注册时,oAuth可能没有用,该公司帐户通常不与任何社交网站或Google关联或链接。
Aftab Naveed

5
我不知道为什么这是可接受的答案?没有回答,真正的问题,只是改革在其他方式的问题
AMD

1
您说:“客户端可以读取存储在JWT中的数据。这可能是一个问题。如果那是一个问题,为什么不使用JWE?
银色

这个答案使苹果和橙子感到困惑。您不应将它们与OAuth 2.0(“授权”规范)进行比较。OP需要了解的是:“资源所有者密码流”-这是作为授予的身份验证。
OnurYıldırım17年

5

问问自己为什么需要使原始令牌无效。

用户登录,将生成令牌,然后关闭应用程序。

用户按下注销键,将生成一个新令牌并替换原始令牌。再一次,一切都很好。

您似乎担心两个令牌都挂在一起的情况。如果用户注销,然后以某种方式使用登录令牌发出请求,该怎么办?这种情况有多现实?这仅仅是注销过程中的问题,还是在许多可能存在多个令牌问题的情况下?

我自己不认为这值得担心。如果有人正在拦截和解码您的加密https数据,那么您将遇到更大的问题。

您可以通过在原始令牌上放置一个过期时间来为自己提供一些额外的保护。因此,如果最终被盗或被盗,那只能在短时间内有效。

否则,我认为您将需要在服务器上具有状态信息。不要将令牌列入黑名单,而是将当前令牌的签名列入白名单。


2
如果您认为某些客户端是恶意的,那么很容易看到会话将被复制并重新使用,因此您需要在服务器上对此进行反击。
Michael Shaw 2015年

1
一个坏主意,这可以稍后被黑客使用,或者仅被强行使用……
CROSP 2015年

2
假设用户想从所有其他设备注销,则无法使用JWT。
AMD公司

@amd不可能吗?如果我添加了nonce =(random)并且用户注销了,请替换现时该怎么办。似乎简单有效。
Simon B.

3

您可以通过将盐值与用户一起存储并将盐作为用户令牌的一部分来处理您提到的JWT问题。然后,当您需要使令牌失效时,只需更改盐即可。

我知道已经过去了几年,但实际上我现在会做不同的事情。我想我会确保访问令牌的生存期相对较短,例如一个小时。我还要确保使用服务器上有状态的刷新令牌,然后当我想结束某人的会话时,可以通过将刷新令牌从服务器中删除来撤销刷新令牌。然后,一个小时后,该用户将被注销,必须再次登录才能重新获得访问权限。


4
但是在这种情况下,它再次变为满状态,因此创建盐或使用任何其他方法的原因是什么,您可以在表中简单存储令牌并在应使其无效时删除它们
CROSP 2015年

2
您还可以基于时间使之失效。
RibaldEddie

在这种情况下,到期时间有什么区别?当用户要从移动客户端注销时,如何根据时间使令牌无效?在这种情况下,似乎没有办法使API无状态。什么是最合适和最安全的解决方案?
CROSP

2
最适合从单个设备注销的方法是确保除盐之外还使用clientId。我建议您查看Oauth-jwt承载令牌规范以了解情况。
RibaldEddie

感谢您的回答,但是我完全不明白为什么在这种情况下应该使用OAuth。
CROSP,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.