sessionStorage vs localStorage vs Cookies for Secure Storage

Before we dive into implementing persistent login sessions in our app, we'll touch on the different storage mechanisms of the web browser. In this lesson, we explore the differences between localStorage, sessionStorage, and cookies.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL - Part Two

Before we dive into implementing a persistent login session, we'll touch on the different storage mechanisms of the web browser. We'll discuss local storage, session storage, and cookies. All three of these mechanisms allows us to store data in key value pairs as strings, in the browser's memory. However, there are key differences between each of them. Local storage is persistent in browser memory. It's accessible through JavaScript only on the client, and it's not automatically sent to the server during an HTTP request. Let's test this out. We can run the following command in our console. Local storage set item and give a key of greeting and a value of Hello World. We can then navigate to where we can see local storage information in our dev tools. In Google Chrome, this is under the application tab. We'll now see a greeting Hello World key value pair. Now if we were to refresh the web page or even close and reopen the tab or the browser, even restart the computer, this data would remain. The only way to delete this particular data is to explicitly delete it, with which we can do with the following command localstorage.removeItem or clear our browser 's memory. Version storage behaves very similar to local storage except for the fact that stored data is deleted once the browser tab or window is closed. It's accessible with JavaScript only, and it's not automatically sent to the server during an HTTP request. We can test this out as well. We'll run the sessionstorage.setItem command in our console, and we can navigate to where we can see session storage information with which would be in the application tab in Chrome, and we'll notice the greeting Hello World key value pair. Refreshing the web page won't delete the data, however if we were to close and reopen the tab or close and reopen the browser, the data will be deleted. Just like local storage, we could also remove the data with the .removeItem command as well. Cookies are persistent in browser memory, are inaccessible with JavaScript on the client when an HTTP only flag is used, and are automatically sent to the server during an HTTP request. Just like local storage, cookies are persistent in memory. This means by refreshing the web page, closing or reopening a browser tab or browser window or even restarting our computer won't delete cookie data. A cookie is often deleted when the cookie is to be used up to an expiration date or by clearing our browser's memory. Another interesting property of a cookie is that it can be tagged with an HTTP only flag. By setting a cookie to HTTP only, we ensure that the cookie can be accessed from the server and as a result can't be tampered with by JavaScript running on the browser. Lastly, unlike local storage or session storage, cookies are automatically sent to the server on every HTTP request. Local storage and session storage data are accessible with JavaScript running on the browser. Because of this, authentication data stored in local storage or session storage are vulnerable to an attack known as Cross-Site Scripting Attack. Cross-Site Scripting is a vulnerability where attackers can inject client-side scripts, or in other words, JavaScript, to run on a web application. To prevent cross-site scripting, we could ensure that all links are from a trusted source. This includes the URLs of HTML image elements and anchor tags, and we could escape untrusted data, which is often automatically done when using a modern front-end framework like React. Cookies, when used with the HTTP only flag, are not accessible with JavaScript running on the browser, and are thus immune to cross-site scripting attacks. We can also set a secure flag to a cookie to guarantee the cookie is only sent over HTTPS. These are some of the reasons why cookies are often used to store tokens or session data. However, cookies are vulnerable to a different type of attack known as Cross- Site Request Forgery. Cross-Site Request Forgery in a nutshell is a type of attack that occurs when one is lured to a malicious website or email, which causes the web browser to perform an unwanted HTTP request to another website which one is currently authenticated. This is an exploit of how the browser handles cookies. Another flag for the cookie, the same site flag, was designed to counter Cross- Site Request Forgery by ensuring that cookies are not sent with cross-site requests. Though the same site flag is new, it's supported by most major browsers. Another additional step to counter Cross-Site Request Forgery is to include a Cross-Site Request Forgery token with every HTTP request, which helps ensure the intended user is making the request. In the next few lessons, we'll see how cookies can be used to ensure a persistent login session and will follow up with how clients can add a Cross-Site Request Forgery token to requests as an additional step to preventing Cross-Site Request Forgery attacks.