RESTful身份validation – 在高负载下导致性能不佳?

对于RESTful Web服务,我们说服务器不应存储任何状态。 现在,对于每个请求,“用户”必须经过身份validation,并且必须拥有他/她希望执行的操作的授权。

现在,每个请求都将包含该用户的授权数据。 这是我的困惑:

假设主页上有登录名和密码字段。 用户输入用户名/密码,该用户名/密码被发送回服务器,用户validation然后返回“某个令牌”。 现在,每个请求都会将此令牌发送到服务器。 问题(S):

  • 后端数据库是否需要有一个单独的表来存储由用户名索引的这些令牌?
  • 假设令牌存储在DB中,则每个请求都需要进行DB调用。 这是否会导致数据库服务器在高负载时成为瓶颈?
  • 如果令牌没有真正存储在DB中,那么存储它的最佳“宁静”位置是什么?
  • 有会议可能不安宁,但后来我没有看到如何扩展身份validation/授权(如上所述)?
  • 如果它不是令牌,那么用户名/密码是否需要反向发送? (听起来像个坏主意:)

我可能误解了RESTful身份validation/授权的概念。 但实际情况是,对于每个http请求,“服务”需要访问数据库以validation凭据吗? 有什么东西可以简化这个过程并仍然坚持宁静的原则吗? 我可以想到有一个存储细节的缓存,并且在服务器重启的情况下,它只是让数据库之旅。 这只是一个可能使系统复杂化的性能优势(可能值得,不知道)。 这是唯一的解决方案吗?

因此,从REST的理论/概念角度(不是必要的实现)如何处理这个问题(如果它是一个问题)? 您的专业经验如何处理这个问题以及Restful是如何处理的?

我们正在研究Restlet + J2EE + MySQL Restful Web服务,我弹出这个问题,但没有令人满意的答案(谷歌,Stackoverflow等)我知道HTTP的基本和摘要授权,但我不熟悉根据上述说明,存储/检索的内部结构。

REST的精神是无国籍。 这并不意味着客户端状态不能由服务持久化,但实际上它确实意味着服务器在内存中保存的客户端状态通常是一件坏事。

您可以做的就是将一个函数保存在用于加密/解密用户信息的内存(即代码)中,而不是将身份validation数据保存在内存中,或者每次都进入数据库进行validation。 这是一种技术,也可以通过以下方式建议:

我应该在cookie中存储什么以在用户登录时实现“记住我”

那么,例如,你要做的是以下内容:

  1. 当客户端首次联系服务时,它没有cookie。
  2. 您发出一个包含用户信息的cookie并使用您的函数“对其进行”签名(运行您的代码的所有服务器都可以)
  3. 当客户端再次联系服务时,您检查它是否有cookie; 如果没有,重复(2)。
  4. 但是,如果它确实有cookie,则会尝试解密(再次使用在您的基础架构中复制的单个函数)并validation您是否可以解包和摘要该用户ID信息。
  5. 这将validation用户并为您提供身份信息,所有这些都无需多次访问DB。 它是RESTful的。

请记住,我描述的这个“function”并不是一个新奇的东西 – 它是一个标准的安全哈希,但它基于一个唯一的私钥,只有你的集体服务器知道。 您可以根据需要旋转这样的键等。

您只能在登录时validation凭据(例如用户名/密码)。 当用户成功登录时,您向他们发送一个包含不可思议的“会话ID”的cookie。 此会话ID成为允许在检查凭据后进一步访问的令牌。 服务器应用程序通过在某些内存数据结构中找到它来validation令牌。 令牌在一段合理的时间后到期,以防止内存耗尽。 如果用户明确注销,则会从内存存储中明确删除令牌(按下“注销”按钮)。

在发送和接收令牌时使用https很重要 – 否则嗅探令牌会让黑客“劫持会话”。 换句话说,从登录到注销,使用https进行整个应用程序工作流程。

RESTful服务应该是无状态的,所以是的,客户端每次调用RESTful服务时都需要提供身份validation凭据。

用某种散列或令牌或会话ID替换用户名/密码没有什么好处。 所有这些都只是不同forms的身份validation,必须针对持久存储中的某些数据进行validation。 会话和令牌的缺点是它们违反了无国籍要求。

如果数据库性能是一个问题,那么使用memcached或其他一些高性能数据缓存。 您可能会发现所有数据库访问都可以从中受益,而不仅仅是检索身份validation凭据。

最后,只要您通过HTTPS进行用户名/密码,就没有问题。 从来没有,通过纯文本HTTP发送重要的身份validation凭据。