• Web

Storing Session Data

From the class:  Session Cookies

So far, we've got a way to uniquely identify a user based on this ID. But what we really want is to be able to store key value pairs-- information about the user. For instance, we might want to know whether or not the user is authenticated or logged into our site. We might even store the user ID that's associated with this session. So a user ID being an actual ID for the user that's in our users table in our database. You might also store something like the contents of a shopping cart. And there's so many examples of key value pairs that we want to store associated with a current session.

So how would we go about doing that? Well, one approach is when we get this ID on the server, we could keep a big hash table in memory and we could go look for the record that's keyed by this ID. And inside of that object or that record, we could store any number of key value pairs for this user, like the user name, whether they're logged in, and so on. Another option is to just use the database itself. We could have a table called sessions, for example. And the primary key for that table would be the string ID, like this. And so we would say, select star from sessions where the ID is equal to whatever this value is.

The third option is we can store these values in the cookie itself. Right now, the cookie is just the ID. But you could imagine we could store a JSON string, which would look like an object. And inside of that object, we could have an ID property, instead of making the cookie value the ID itself. This is really one of the simplest options, and it's simple to implement and it's also simple to maintain. We don't have to have a table full of potentially lots and lots and lots of session records. And in memory is not very good if you have multiple servers and the user could be bouncing back and forth between the servers. And so cookie is really good implementation.

There's one problem is that the cookie has a size limit of 4,000 bytes. So 4K is the biggest we can make this cookie. But that's usually fine for the kinds of things that we want to store in session.

So let's update our implementation to storage a JSON object instead of just the ID. First off, let's create a function called set session. We've got one forget, and now we'll get another one for set. And I'll pass into that function the request and the response. And we'll move this code up into that function. And just so that we don't forget, I'll call it right before we end the responsive. So set session, and I'll pass in the request and the response.

All right. The purpose of this function is just to modularize our code a little bit. And inside of set session, I'm going to create a variable called serialized. If you ever hear this vocabulary word serialized, it means we're going to take some form of an object or a variable and convert it into another form. And in this case, what we're going to do is to convert our session that's stored on the request, we're going to convert it from an object into an encoded URI component JSON string.

So I'll call this stringify method of JSON, or you can use whatever JSON library you have for your framework. And this is going to turn this object into a string that we can send over the wire. And then, just to be safe, on that resulting string, I'm going to call encode URI components. And that'll make sure that the value is safe to use in URLs. Remember back in the get session, a little bit further up here in parse cookie, we decode the URI component. So that's where we're actually-- down here is where we're going to actually encode the value into a URI-compliant string.

OK. Now that we have that value, that serialized value, we're going to set the header AP dot session equal to the serialized value instead of the raw session ID. And everything else we should be able to keep the same for setting the session. Now we need to update the getSession method to be able to work with JSON objects. Instead of doing it on one line, I'm going to split it up into an if statement. I'll say if the cookie exists, then we just need to de-serialize it from a JSON string back into an object. So I'll assign the session property of request equal to JSON dot parse. And we'll pass in the cookies string as the parameter.

And if there's no session yet, we'll set request dot session equal to what we had before. I'll just get rid of the first part of that. And in this-- now instead of being just a raw ID, it's going to be a JavaScript object, which has a property called-- we'll just call it underscore ID to reduce the chance of conflicts. So the first time a user comes to our site, we're going to call get session from the app logic down below, and it will set session equal to a new object with an ID.

And then right before we end the request, we call set session, which is going to grab that session that came from here, JSON stringify it, and then make sure that it's compliant as a URI. And then we'll set the header set cookie app session equal to that value, that serialized value. And in case you forgot, down below in the app code-- oops, down in the app code, this is where we call get session. And then right before we end the request, we call set session.

Let's go ahead inside of here. Let's set an actual session value. So I'll say request dot session. I don't know. Let's just call it login name. So we can put an actual key and a value onto the session object that will be preserved over multiple requests. And right before that line, let's print out to the log the value of the sessions, so we can make sure that the browser is sending it up properly and we're able to retrieve it correctly.

Then over in the other console, let me start up the server here. And I'll curl just for the headers, local host 3,000. And now what we get back is the session. And notice that on the server, it prints out the object with this new ID. And the set cookie header is a little bit harder to read now, because we now have the value as a JSON string that is also being URI encoded. So it's getting a bit hard to parse just by I.

Let's head over to a browser and see this in action, where we're actually able to maintain the session over time. Once again, right click and clear the previous cookie so that it doesn't conflict with our new scheme, and refresh the browser. And now notice that we've got this new app session value. And over in the right, it prints out the full value of the session object. This is the second request that gets made to the favicon, if you remember that. This was the original request.

And at that point, we just have an ID. But then later on, we actually set that login-- the login property. And when this second request gets made, we now have that login property. It's been persisted. And if we refresh the browser multiple times, we're now going to have that login property set forever, until we reset or delete the session and start over.

So this provides a nice easy place to put values like this login information that we want to keep for a user over multiple browser sessions, and potentially for a long period of time.