Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of external requests when serving a resource

So, I have a web application that makes a lot of requests to the server for data. A project requirement is to have very fast server response times. The server is hosted on a cloud based platform.

The app uses sessions to keep track of user authentication once they've logged in. Since it's hosted on a cloud provider, I'm using a cache to back up session storage (in my case it's Auzre cache, but if you're unfamiliar with that think Redis)

The current flow is like this:

  • The user accesses a resource
  • Trying to get the session based on the session ID via the cache. This is a cache request.
  • User is authenticated via session state (if logged in).
  • Request for data is sent, usually via cache.
  • Data is returned to the user.

The problem with this approach is that it's hitting the cache twice. Removing the session altogether caused a significant speed improvement (about 50%).

I was considering hitting the cache once, asking for both the key I need for the user, and the SessionID to save the extra round trip. However, I've never seen this approach before, and it requires 'rolling my own session' as I'd have to generate the session IDs and such. I feel like there might be a simpler, easier way.

So, what would be the most efficient way to serve the user a resource and authenticate them?


Note: I'm using ASP.NET MVC/ WebAPI with C# but I don't find that very relevant to the question, so I left the language and platform out of the question because of it.

like image 575
Benjamin Gruenbaum Avatar asked Apr 21 '14 20:04

Benjamin Gruenbaum


People also ask

How many requests can a pod handle?

You can handle as much request as your infrastructure can handle. It can be changeable based on the infrastructure.

What does 100m CPU means?

cpu: 100m. The unit suffix m stands for “thousandth of a core,” so this resources object specifies that the container process needs 50/1000 of a core (5%) and is allowed to use at most 100/1000 of a core (10%). Likewise 2000m would be two full cores, which can also be specified as 2 or 2.0 .

What are resource requests?

One of the main documents of any project is the Project Resource Request. This form covers information such as resources, a project role, qualifications, and requested dates. The Project Resource request can be a sensitive document, so you must have a detailed plan in action.

What is the difference between resource limit and request?

Requests and LimitsRequests are what the container is guaranteed to get. If a container requests a resource, Kubernetes will only schedule it on a node that can give it that resource. Limits, on the other hand, make sure a container never goes above a certain value.


1 Answers

You would want to combine the authenticate and resource request steps into one single request. Not only is this faster, it is also safer than your implementation. Consider the following scenario:

  1. User authenticate to the server. Result is success.
  2. Authentication is changed. (e.g. user changes password, admin decides to lock the user account, etc.)
  3. User makes a request using the sessionID in step 1.

To ensure that the user is not granted access to the resource, you'd want to authenticate the user precisely at step 3. But that doesn't make sense, you've already authenticated this user previously in step 1...

HTTP, in is core, is designed exactly to do this. There are various ways to pass authentication information along with the request, such as:

  1. Write the authentication information in the content (stupid, but works)
  2. Include authentication in the url, e.g. example.com/pic/123?sessionID=abc (better, but makes your url ugly and long)
  3. Store session info in cookie (better, but what if the client does not support cookie? what about cookie expiration?)
  4. Authenticate HTTP header (my best personal recommendation)

HTTP itself has an authenticate header meant to be compatible with "basic authentication" (it is well defined, look it up if you're interested). But you can implement your own custom header.

Any cache lookup is bound to be slow (compared to computation), so you should omit the cache for the authentication part all together. Your server should be stateless; i.e. do not keep track of login sessions. How do you know if the sessionID is valid? Put a timestamp on it. And to avoid others faking the sessionID, sign it as well.

So, your HTTP request would look something like this (pseudo code):

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

Implement your own signing method, sort of like a hash function (you can use HMAC), and keep the key securely on the server. If the signature matches, you know you've signed this previously at the login, and it has to be from your server. A timestamp helps you detect session expiration and also protect against replay attacks.

Now in your server, do something like this:

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

If you need to do login + session authenticate + resource request in one request, then there're simply just 2 ways for authentication. Users can either provide a username/password combination, or a session key. Think about this scenario, which comes from an API I worked on:

  1. user register with username/password combo
  2. server responds registration success / failure (e.g. username already taken)
  3. if it was a success, user now logins with username/password combo
  4. server returns a session token

Wouldn't it be simpler (and faster) if we do it this way:

  1. user register with username/password combo
  2. if it is success, respond "reg success" and "sessionToken=xxxxxx". if it is failure, respond "reg failure".

I hope this give you some idea.

like image 110
kevin Avatar answered Sep 24 '22 08:09

kevin