RESTful身份验证 - 在高负载下导致性能不佳?

时间:2011-03-04 21:37:10

标签: java web-services performance restful-authentication restlet

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

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

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

  • 后端数据库是否需要单独的表来存储这些内容 用户名索引的令牌?
  • 假设令牌存储在数据库中,则每个请求都需要进行数据库调用。这是否会导致DB服务器在高负载时成为瓶颈?
  • 如果令牌没有真正存储在数据库中,那么存储它的最佳'宁静'位置是什么?
  • 会议可能不太安宁,但后来我没有看到如何放松身份验证/授权(w.r.t.以上几点)?
  • 如果它不是令牌,那么用户名/密码是否需要在前后发送? (听起来不错的主意:)。

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

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

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

3 个答案:

答案 0 :(得分:8)

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

您可以在内存中保留功能(即代码),而不是将身份验证数据保留在内存中,或者转到数据库进行验证。用于加密/解密用户信息。这是一种技术,也可以通过以下方式建议:

What should I store in cookies to implement "Remember me" during user login

因此,举例来说,您将采取以下措施:

  1. 当客户首次联系该服务时,它没有cookie。
  2. 您发出一个包含用户信息的cookie,并使用您的函数“对其进行”签名(运行您的代码的所有服务器都可以这样做)
  3. 当客户再次联系该服务时,您检查它是否有cookie;如果没有,重复(2)。
  4. 但是,如果它确实有cookie,则会尝试解密(再次使用在您的基础架构中复制的单个函数)并验证您是否可以解包和摘要该用户ID信息。
  5. 这将验证用户并为您提供身份信息,所有这些都无需多次访问DB。它是RESTful。
  6. 请记住,我所描述的这个“功能”并不是一件新奇的东西 - 它是一个标准的安全哈希,但是它基于一个唯一的私钥,只有你的集体服务器知道。您可以根据需要旋转这样的键等。

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

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

用某种哈希或令牌或会话ID替换用户名/密码没有任何实际好处。所有这些都只是不同形式的身份验证,必须针对持久存储中的某些数据进行验证。会话和令牌的缺点是它们违反了无国籍要求。

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

最后,每次发送用户名/密码都没有问题,只要您通过HTTPS进行操作即可。永远不要通过纯文本HTTP发送重要的身份验证凭据。