Cookie Authentication
Overview
Cookie-based authentication stores session information in encrypted cookies. The server validates the cookie on each request. Unlike JWT, cookies are stateful and managed by the server.
Implementation
1. Configure Cookie Authentication
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "MyApp.Auth";
options.LoginPath = "/login";
options.LogoutPath = "/logout";
options.AccessDeniedPath = "/access-denied";
options.ExpireTimeSpan = TimeSpan.FromHours(1);
options.SlidingExpiration = true;
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
});
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
2. Login Implementation
app.MapPost("/api/auth/login", async (LoginRequest request, HttpContext context) =>
{
// Validate credentials
if (request.Email == "user@example.com" && request.Password == "password")
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, request.Email),
new Claim(ClaimTypes.Email, request.Email),
new Claim(ClaimTypes.Role, "User")
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1)
};
await context.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return Results.Ok(new { message = "Login successful" });
}
return Results.Unauthorized();
});
3. Logout Implementation
app.MapPost("/api/auth/logout", async (HttpContext context) =>
{
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Results.Ok(new { message = "Logged out successfully" });
});
4. Get Current User
app.MapGet("/api/auth/user", (HttpContext context) =>
{
var user = context.User;
if (!user.Identity.IsAuthenticated)
return Results.Unauthorized();
return Results.Ok(new
{
email = user.FindFirst(ClaimTypes.Email)?.Value,
name = user.FindFirst(ClaimTypes.Name)?.Value,
role = user.FindFirst(ClaimTypes.Role)?.Value
});
}).RequireAuthorization();
Cookie vs JWT
| Aspect | Cookies | JWT |
|---|---|---|
| State | Stateful (server session) | Stateless |
| Storage | Server-side | Client-side |
| Scalability | Requires session store | Highly scalable |
| Security | HttpOnly, Secure, SameSite | Signature verification |
| Use Case | Traditional web apps | APIs, mobile apps |
| CSRF | Vulnerable (needs protection) | Not vulnerable |
| Size | Small cookie | Larger token |
Best Practices
- Always use HTTPS in production
- Set HttpOnly to prevent JavaScript access
- Use Secure flag for HTTPS-only cookies
- Set SameSite to prevent CSRF
- Implement sliding expiration for better UX
- Use anti-forgery tokens for state-changing operations