10

我已经开始设计一个 RESTful API,我正在考虑如何处理身份验证。我想使用某种身份验证令牌,但我不能使用 OAuth 或类似的基础设施,所以我必须自己处理它。

此 API 的要求之一是它必须具有良好的性能,足以在需要扩展之前处理大量请求;我关心的是如何尽可能少地对每个请求进行验证令牌(完整性、到期、IP 地址等)所需的时间。

我想令牌应该是某种散列而不是包含用户信息的加密字符串,因为解密时间会很长。

我读过我可以将令牌存储在内存中的哈希表中,其中键是令牌,值是处理请求所需的用户信息,但是如何在集群环境中使其工作每个“节点”上的哈希表?

我是否应该每次都将令牌放在数据库表上并点击数据库并手动处理过期票证的保留?

可能这对这个问题并不重要,但我将 Spring MVC 用于 RESTfull API。

提前致谢。

4

3 回答 3

5

我通过使用内存缓存和数据库缓存解决了我的问题。这是我的解决方案的摘要,可以帮助任何有相同任务的人。

  • 用户登录并在那一刻生成唯一密钥并将其发送回用户。
  • 该登录令牌(基本上是带有一些处理的 GUID)也存储在 db 表中,其中包含其他信息,如过期时间以及用户的信息和角色。相同的信息也存储在内存中(谷歌番石榴哈希表,其中令牌是键)
  • 正如@ipa 建议的那样,令牌必须与授权令牌中的每个 api 调用一起传递
  • 服务器代码检查令牌是否在其内存缓存中 用户信息是否已经可用,否则(例如 api 调用在集群中的另一个节点上完成) 令牌在令牌数据库中搜索
  • 找到令牌后,您可以检查过期、角色等...

这提供了良好的性能和安全性,可以使用任何算法生成令牌,即使是相对较慢的算法,因为您不必在每次 api 调用时重新计算它。这也适用于可以水平扩展的无状态服务。

于 2014-05-04T15:06:38.620 回答
3

我假设您使用 https,因此所有流量都是加密的。我建议以下原则之一。

基本认证

您可以在请求的 Authorization 标头中添加凭据。此凭证使用 Base64 编码(见下文)。此凭据可以在每个请求上发送,然后与您的数据库一起检查。为了获得更快和更少的 IO 密集度,您仍然可以使用缓存。一旦我实现了这样一个没有缓存的 API,并且每秒能够处理数千个请求。

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

授权令牌

有不同的方法可以使用令牌来实现您的想法。一个常见的问题是每个 API 用户都有自己的令牌,通常称为 API 密钥,它永不过期。另一个是您首先必须授权(基本身份验证),然后取回过期的令牌。然后将其用作 api 密钥一段时间。

无论哪种方式,您都必须决定是否使用缓存。我会保持简单并进行基本身份验证并每次检查数据库。几乎每个框架都对这种方法有很好的支持,因为它是简单的 http。如果这会导致性能问题(无论如何我建议进行性能测试),请尝试将带有您的凭据的表添加到 JPA 缓存中。如果你想用过期的令牌实现一些东西,看看 Infinispan。

于 2014-05-02T11:24:51.330 回答
0

您可以将令牌存储在 Redis 中。如果要将其存储在数据库中,请确保优化服务器(如果您正在管理它)以进行读取操作。我有几个实现,人们也使用了键值存储。哈希表也是个好主意。

于 2017-03-15T14:49:40.550 回答