Cookies-Based Authentication vs Token-Based Authentication

The Tech Platform
4 min readJul 4, 2024

--

Understanding the difference between cookie-based and token-based authentication is crucial because it helps developers make informed decisions when designing and securing their applications.

Cookies-Based Authentication vs Token-Based Authentication

Let’s explore why this knowledge matters:

Cookies-Based Authentication vs Token-Based Authentication

Let’s consider a simple scenario where we have a web application that allows users to access a restricted resource (e.g., a dashboard) after logging in. We’ll explore how both cookie-based and token-based authentication work in this context.

Cookie-Based Authentication

Cookie-based authentication is a method where user authentication information is stored and managed using cookies. These cookies are sent between the client (usually a web browser) and the server.

Here we will see how this works:

STEP 1: User Login:

  • When a user logs in, the server validates their credentials (username and password).
  • If the credentials are correct, the server creates an authentication cookie.
  • This cookie contains a session ID or user-specific data (encrypted and signed).
  • The server sends the back cookie to the client (usually the browser).

STEP 2: Subsequent Requests:

  • The browser includes the authentication cookie in the request headers when the user accesses a restricted resource (e.g., the dashboard).
  • The server decrypts and verifies the cookie to identify the user.
  • The server grants access to the requested resource if the cookie is valid.

STEP 3: Session Management:

  • The server maintains the session state (e.g., session duration, expiration).
  • The server invalidates the cookie if the user logs out or the session expires.

Advantage: Simplicity, session management, domain-bound.

Disadvantage: Vulnerable to CSRF attacks, limited scalability.

Example Code:

In Startup.cs: We configure cookie-based authentication using services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).

public void ConfigureServices(IServiceCollection services)
{
// Other services configuration...

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login"; // Customize login path
options.AccessDeniedPath = "/Account/AccessDenied"; // Customize access denied path
});

// Other configurations...
}

We customize the login path and access denied path.

In AccountController.cs: The Login action handles user login. If the user’s credentials are valid, we create an authentication cookie using HttpContext.SignInAsync. If not, we display an error message.

public async Task<IActionResult> Login(LoginViewModel model)
{
// Validate user credentials (e.g., against a database)
if (IsValidUser(model.Username, model.Password))
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, model.Username),
// Add other claims (e.g., roles)
};

var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));

return RedirectToAction("Dashboard");
}

ModelState.AddModelError("", "Invalid credentials");
return View(model);
}

In DashboardController.cs: The Dashboard action is marked with [Authorize], requiring authentication. If the user has a valid authentication cookie, they can access the dashboard.

[Authorize] // Requires authentication
public IActionResult Dashboard()
{
// Display dashboard content
return View();
}

Token-Based Authentication

Token-based authentication is a method where authentication is performed using tokens. Tokens verify the user’s identity instead of relying on session cookies (like cookie-based authentication).

Let’s see how this works:

STEP 1: User Login:

  • After successful login, the server generates a JWT (JSON Web Token).
  • The JWT contains claims (e.g., user ID, roles) and is signed with a secret key.
  • The server sends the JWT to the client (usually a Single-Page Application or mobile app).

STEP 2: Subsequent Requests:

  • The client stores the JWT (e.g., in local storage).
  • For each subsequent request (e.g., fetching data from an API), the client includes the JWT in the Authorization header.
  • The server verifies the JWT’s signature using the secret key.
  • The server grants access if the signature is valid and the token hasn’t expired.

STEP 3: Statelessness:

  • Unlike cookies, tokens are stateless. The server doesn’t maintain a session state.
  • This makes token-based authentication highly scalable and suitable for microservices and APIs.

Advantage: Stateless, immune to CSRF attacks, scalable.

Disadvantage: Requires additional setup (e.g., JWT handling).

Read: Secure Authentication via JSON Web Tokens (JWT)

Example Code:

In Startup.cs: We configure token-based authentication using services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).

public void ConfigureServices(IServiceCollection services)
{
// Other services configuration...

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "your-issuer",
ValidAudience = "your-audience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-secret-key"))
};
});

// Other configurations...
}

We set up validation parameters for JWTs.

In AuthController.cs: The GenerateToken action generates a JWT after a successful login. We create claims (e.g., user ID) and sign the token using a secret key. The client (SPA) receives this token.

public IActionResult GenerateToken(string username)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
// Add other claims (e.g., roles)
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-secret-key"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
issuer: "your-issuer",
audience: "your-audience",
claims: claims,
expires: DateTime.UtcNow.AddHours(1), // Set token expiration
signingCredentials: creds
);

return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
}

In DashboardController.cs: The Dashboard action is marked with [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)], requiring a valid JWT. They can access the dashboard if the client includes a valid JWT in the request.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] // Requires JWT
public IActionResult Dashboard()
{
// Display dashboard content
return View();
}

Conclusion

Choose the approach based on your application’s needs, security requirements, and client type.

Use Cookie-Based Authentication When:

  1. Traditional Web Apps with Server-Side Rendering: If you’re building a web application with server-side rendering (e.g., ASP.NET MVC) and need a straightforward authentication mechanism.
  2. Session Management Requirements: When you want to manage user sessions easily (e.g., controlling session duration, handling logouts).

Use Token-Based Authentication When:

  1. Single-Page Apps (SPAs): If you’re developing SPAs using frameworks like React, Angular, or Blazor.
  2. APIs and Microservices: For securing APIs or microservices.

Both methods play essential roles in modern web development, and understanding their differences empowers developers to make informed decisions.

--

--

The Tech Platform

Welcome to your self-owned "TheTechPlatform" where the subscription brings together the world's best authors on all Technologies together at one platform.