Cookie-Based Authentication vs Token-Based Authentication
What to choose?
So, what are your plans? Are you attempting to replace cookie-based authentication with cookieless authentication in your web application? Be cautious, and proceed with caution…
What is Authentication?
Let’s start by understanding what authentication is. Authentication is the process of confirming a certain entity’s identity before allowing access to a protected resource. There are two key advantages of using ‘Authentication’ in a system.
- Restrict unauthorized access and protect the resource.
- Personalization based on the authentication token can improve the user experience.
Cookies for Authentication
Cookies are small pieces of information that allow a website to recognize a user and their preferences.
Cookies that are set during a session are stateful elements. They hold data that the server transmits to the browser for short-term storage. Both the client and the server store the authentication data contained in a cookie. The server maintains a database of active sessions, while the browser keeps track of the active session’s identification. When a request is made to the server, the session id is used to check if the session is still valid by looking up information such as user roles or rights for authentication. Every time the page is requested, the browser sends the cookie back to the server.
How it works?
- The end-user enters the login credentials.
- The server verifies the identity of the user and creates a session which is then stored in a database.
- A cookie with the session id is placed in the user’s browser agent.
- The session id is checked against the database on subsequent requests, and if valid, the request is processed.
- The session is terminated both client-side and server-side when a user logs out of the app.
Let’s explore a real-world example where cookies are used for authentication
- A user needs to login into his LMS account. He enters his credentials ( the username and the password)
2. The server verifies the user's identity, persists identity-related data against a session id in memory, and responds back to the client with the ‘set-cookie’ header.
- Create a simple cookie from the server backend and add the cookie to the servlet response.
Cookie cookie = new Cookie("cookie1" , "xxx");
- Create a cookie with some advanced configurations
Cookie cookie = new Cookie("cookie1" , "xxx");
cookie.setMaxAge(60); //sets expiration after one minute
cookie.setSecure(true);// declares the cookie may only be transmitted using a secure connection
cookie.setHttpOnly(true);// prevents client-side scripts from accessing data
3. In subsequent requests, the cleint sends authorization requests again with the cookie which has the session id
4. The server validates the session id against the database entry and grants the authorization
Why are cookies so appealing?
- Less source code
Cookies will be appended to the request automatically, requiring less code because the developer will not have to incorporate them manually.
- Small storage
- Safe for XSS attacks
The HttpOnly flag can be used to limit client-side access. Because most XSS attacks use malicious JS code, this minimizes the likelihood of cross-site scripting (XSS) assaults on your application.
All current browsers include cookie-clearing options. Users can manually locate and erase cookies from their hard drives. Cookies can be made available for a specific amount of time.
Things to think about when using cookies
- Vulnerable to CSRF
Cookies are vulnerable to cross-site request forgery (CSRF) attacks. The SameSite property lets you specify whether cookies should be provided to third-party apps using the Strict or Lax settings. While a strict configuration can help prevent CSRF attacks, it can also give a bad user experience.
- Not supporting across domains
Cookies can only be sent between domains or subdomains within the same domain.
- Less support for Native Applications
Cookies do not work well with all native mobile applications.
- Less scalable
When there are a lot of users and a lot of reads/writes to the database, scaling might be difficult while increasing the latency.
Tokens for authentication
JSON Web Token (JWT) is an open standard of transmitting information securely between two parties.
It has three main parts header, payload, and signature. As JWTs can be signed and encrypted, when a server receives a JWT, it can be certain that the data it includes is trustworthy because the source has signed it. After a JWT is sent, no one can change it.
JWT in its serialized form;
A typical JWT ;
How it works?
Let’s explore a real-world example where tokens are used for authentication
- A user logs in to a website using the username and password
2. Here in this example, I’m using the inbound protocol as OIDC and using the ‘Authorization code’ grant type to request an access token from the server. So here, if the user’s credentials are verified the server will send back a code to the client. The client needs to pass that authorization code to retrieve the security token (access token) from the server.
3. For each user, the server generates a security token with a unique id if the code is valid.
This token is stored client-side in local storage, session storage, or a cookie.
How does SSO work here?
- Assume the website contains a button to log in to a User Portal from the website. So upon the button click the secure token must be passed in the URL as a parameter or should be posted to the User Portal directly.
- The secure token is verified by the User Portal, and the user is automatically logged in.
Is JWT the trend now?
- Seamless Across Devices and Domains
It’s simple to expose APIs to different services and domains using a token-based authentication mechanism with CORS enabled. Furthermore, this is compatible with all native programs.
The method of token authentication is stateless. Because each token is self-contained, including the data required to confirm its validity and send user information through claims, the web server will not need to keep a record of them. On successful login, the server just needs to sign tokens and verify that incoming tokens in requests are legitimate.
Because the Token-based authentication solution uses signed tokens, only a private key (used to produce the authentication token) may validate it when it arrives at the server. As a result, this method can be regarded as more secure.
Every time the user requests a page, cookie-based authentication needs the server to do an authentication lookup. The token-based authentication can be used to eliminate round-trips when using tokens. The access token and public key are appended to the permission header on every page request in cookieless authentication.
Tokens are typically created with an expiration date after which they become invalid. Then, for re-authentication, a new token must be obtained.
Challenges with Token-Based Authentication
- Overhead of storing data
Storing a lot of data in the token makes it huge, which slows the requests and impacts the product performance.
- Client-Side storage issues
The token can be stored inside a cookie, session storage, or local storage but there is some set of common challenges which are associated with these storages. In addition to that, an attacker could hijack a token on the client-side, making it vulnerable to cross-site scripting (XSS) assaults.
- Single-key Token
One of the major drawbacks of cookieless authentication is that access tokens are based on a single key. Tokens that employ JWT rely on a single authentication key.
The location of the session information is the key difference between the cookie and token-based approaches. The burden of storing the session falls on the server in the cookie-based approach, whereas the client is responsible for preserving the session information (which self contains the token) in the token-based approach.
The cookie-based authentication method is based on the idea of sharing the ID with the client via a cookie file, while the rest of the information is stored on the server in the session file. The token-based authentication approach is based on the idea that a user only requires a token to have their requests approved by the server, which simply needs to validate a signature. Because it cannot be tampered with, the token is safe to use.
Both systems have flaws that can be readily fixed with alternative remedies. At the end of the day, developers must choose which solution best suits their needs and applications.