服务资源时的外部请求数

时间:2014-04-21 20:57:13

标签: session server-side

所以,我有一个Web应用程序向服务器发出大量数据请求。项目要求是具有非常快的服务器响应时间。服务器托管在基于云的平台上。

应用程序使用会话在用户登录后跟踪用户身份验证。由于它托管在云提供商上,我使用缓存备份会话存储(在我的情况下,它是Auzre缓存,但如果你“对Redis感到不熟悉”

目前的流程如下:

  • 用户访问资源
  • 尝试通过缓存基于会话ID获取会话。这是一个缓存请求。
  • 用户通过会话状态进行身份验证(如果已登录)。
  • 通常通过缓存发送数据请求。
  • 将数据返回给用户。

这种方法的问题在于它会两次点击缓存。完全删除会话导致显着的速度提升(约50%)。

我正在考虑一次点击缓存,询问用户需要的密钥,以及保存额外往返的SessionID。但是,我之前从未见过这种方法,它需要“滚动我自己的会话”,因为我必须生成会话ID等。我觉得可能有一种更简单,更简单的方式。

那么,为用户提供资源对其进行身份验证的最有效方法是什么?


注意:我正在使用带有C#的ASP.NET MVC / WebAPI,但我发现这个问题与这个问题无关,所以我将语言和平台排除在外它

2 个答案:

答案 0 :(得分:2)

您可能希望将身份验证和资源请求步骤合并为一个请求。这不仅速度更快,而且比实施更安全。请考虑以下情形:

  1. 用户向服务器进行身份验证。结果很成功。
  2. 身份验证已更改。 (例如,用户更改密码,管理员决定锁定用户帐户等)
  3. 用户在步骤1中使用sessionID发出请求。
  4. 为确保未授予用户访问资源的权限,您需要在步骤3中准确地对用户进行身份验证。但这没有意义,您之前已在步骤1中对此用户进行了身份验证。

    HTTP,in是核心,设计完全是为了做到这一点。有多种方法可以将身份验证信息与请求一起传递,例如:

    1. 在内容中写入身份验证信息(愚蠢但有效)
    2. 在网址中包含身份验证,例如example.com/pic/123?sessionID=abc(更好,但会让你的网址难看又长)
    3. 将会话信息存储在cookie中(更好,但是如果客户端不支持cookie会怎么样?cookie过期怎么办?)
    4. 验证HTTP标头(我最好的个人推荐)
    5. HTTP本身有一个身份验证标题,旨在与“基本身份验证”兼容(如果您感兴趣,可以对其进行定义,查找)。但是你可以实现自己的自定义标题。

      任何缓存查找都必然很慢(与计算相比),因此您应该一起省略身份验证部分的缓存。你的服务器应该是无状态的;即不要跟踪登录会话。你怎么知道sessionID是否有效?把时间戳放在上面。并且为了避免其他人伪造sessionID,也要签名。

      因此,您的HTTP请求看起来像这样(伪代码):

      var request = new HttpRequest();
      request.url = "example.com/pic/123";
      request.Headers["CustomAuth"] = "id=abc&t=123456789&s=01de45890a";
      

      实现您自己的签名方法,有点像哈希函数(您可以使用HMAC),并将密钥安全地保存在服务器上。如果签名匹配,您知道您之前已在登录时签名,并且必须来自您的服务器。时间戳可帮助您检测会话过期并防止重放攻击。

      现在在您的服务器中,执行以下操作:

      public void Get(){
          var authHeader = Request.Headers["CustomAuth"];
          if(!validate(authHeader)){
              Response.StatusCode = 404;
              Response.End();
          }else{
              //something else
          }
      }
      

      如果您需要在一个请求中执行登录+会话身份验证+资源请求,那么只需要两种身份验证方式。用户可以提供用户名/密码组合或会话密钥。想想这个场景,它来自我所使用的API:

      1. 用户注册用户名/密码组合
      2. 服务器响应注册成功/失败(例如已经使用的用户名)
      3. 如果成功,用户现在使用用户名/密码组合登录
      4. 服务器返回会话令牌
      5. 如果我们这样做会不会更简单(更快):

        1. 用户注册用户名/密码组合
        2. 如果成功,请回复“reg success”和“sessionToken = xxxxxx”。如果失败,请回复“reg failure”。
        3. 我希望这会给你一些想法。

答案 1 :(得分:0)

此外,您可以通过修改/限制服务器上的设置来删除服务器端的身份验证,以满足仅来自托管您的Web应用程序的IP的请求。只有经过身份验证后,您的Web应用程序才会将请求传递给服务器,因此所有到达数据服务器的请求都将自动提供,而不会检查任何身份验证。在这种情况下,您只需要一次缓存命中即可检查用户是否经过身份验证并立即点击服务器。