Session and Cookies
Level: Beginner to Intermediate
HTTP is stateless. Cookies and session help web applications remember small pieces of information between requests.
- HTTP stateless meaning: Each request independent, server doesn't remember previous requests
- Why stateless matters: Browser can't know if user logged in (server forgets after response)
- Cookie definition: Small data stored on client browser, sent with every request
- How cookies work: Server sends
Set-Cookieheader, browser stores cookie, sends it back on next request - Reading cookies:
Request.Cookies["name"]returns cookie value - Writing cookies:
Response.Cookies.Append("name", "value", new CookieOptions { HttpOnly = true, Secure = true }) - Cookie options: HttpOnly (no JavaScript access), Secure (HTTPS only), SameSite (CSRF protection), Expires (expiration date)
- Session definition: Server-side storage of user data, identified by session ID cookie
- Session storage: In-memory (development), Redis (production), SQL Server (distributed)
- School Management session: Session["UserRole"] = "Teacher", Session["StudentId"] = 101 (remembers user during visit)
app.UseSession(): Middleware to enable session (add to Program.cs)- Cookies vs Session: Cookie stores small data on client (password remember), Session stores large data on server (shopping cart)
- Security: HttpOnly prevents XSS access, Secure requires HTTPS, SameSite prevents CSRF
- Common mistakes: Storing sensitive data in cookies (send encrypted!), not setting HttpOnly (XSS attack), not using HTTPS with secure cookies
- Cookie security options: Always set HttpOnly=true, set Secure=true for HTTPS, set SameSite for CSRF protection
- Common mistakes with user state: Storing passwords in session, forgetting to clear session on logout, using in-memory session for distributed apps
HTTP is Stateless
Each HTTP request is independent.
Example:
Request 1: GET /login
Request 2: GET /dashboard
By default, the second request does not automatically know who made the first request.
Cookies and session help maintain small pieces of user state.
What is a Cookie?
A cookie is small data stored in the browser.
The browser sends cookies back to the server with future requests.
Common uses:
- user preference
- selected language
- theme choice
- session id
- authentication cookie
Set a Cookie
The browser stores:
Theme=dark
Read a Cookie
[HttpGet("theme")]
public IActionResult GetTheme()
{
if (Request.Cookies.TryGetValue("Theme", out var theme))
{
return Ok(new { theme });
}
return Ok(new { theme = "light" });
}
Delete a Cookie
[HttpPost("clear-theme")]
public IActionResult ClearTheme()
{
Response.Cookies.Delete("Theme");
return NoContent();
}
Secure Cookie Options
var options = new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Expires = DateTimeOffset.UtcNow.AddDays(7)
};
Response.Cookies.Append("SchoolPreference", "compact-view", options);
| Option | Meaning |
|---|---|
HttpOnly | JavaScript cannot read the cookie |
Secure | Cookie is sent only over HTTPS |
SameSite | Helps reduce cross-site request risk |
Expires | Controls cookie lifetime |
What is Session?
Session stores data on the server for a user.
The browser usually stores only a session id cookie.
Browser: session id
Server: session data
Session is useful for temporary user-specific data.
Examples:
- selected branch during login
- temporary wizard state
- selected academic year
- small non-critical preferences
Enable Session
Session must be registered and added to the middleware pipeline.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
var app = builder.Build();
app.UseSession();
app.MapControllers();
app.Run();
Important:
AddDistributedMemoryCache -> AddSession -> UseSession
Write Session Data
[HttpPost("select-academic-year")]
public IActionResult SelectAcademicYear(string year)
{
HttpContext.Session.SetString("AcademicYear", year);
return Ok(new { message = "Academic year selected." });
}
Read Session Data
[HttpGet("academic-year")]
public IActionResult GetAcademicYear()
{
var year = HttpContext.Session.GetString("AcademicYear");
if (year == null)
{
return Ok(new { year = "2026-2027" });
}
return Ok(new { year });
}
Session Stores Strings and Bytes
Built-in session methods:
HttpContext.Session.SetString("Key", "Value");
HttpContext.Session.GetString("Key");
HttpContext.Session.SetInt32("StudentId", 101);
HttpContext.Session.GetInt32("StudentId");
For complex objects, store only small identifiers and load details from the database when needed.
Cookies vs Session
| Feature | Cookies | Session |
|---|---|---|
| Stored where? | Browser | Server |
| Sent with request? | Yes | Session id cookie is sent |
| Good for | Small preferences | Temporary server-side state |
| Size | Small | More flexible, but should still be small |
| User can modify? | Plain cookies can be changed | Server data cannot be directly changed |
| Needs server storage? | No | Yes |
Authentication Note
Do not build login security by manually storing usernames in cookies.
Bad:
Response.Cookies.Append("UserName", username);
This does not prove the user is authenticated.
For real authentication, use ASP.NET Core authentication:
- cookie authentication
- JWT bearer authentication
- ASP.NET Core Identity
- external providers
This article explains basic cookies/session, not full authentication.
School App Examples
| Scenario | Good Choice |
|---|---|
| Remember selected theme | Cookie |
| Remember selected language | Cookie |
| Store temporary admission form step | Session |
| Store logged-in user identity | Authentication system |
| Store marksheet file | Database/file storage, not session |
| Store password | Never store in cookie or session |
Common Mistakes
| Mistake | Better Approach |
|---|---|
| Storing sensitive data in plain cookies | Use secure authentication mechanisms |
Forgetting UseSession() | Add session middleware |
| Storing large objects in session | Store ids and load from database |
| Assuming cookies are secure by default | Set HttpOnly, Secure, SameSite |
| Using session as a database | Keep session small and temporary |
Putting UseSession() after endpoints | Add it before controllers/endpoints that need it |
Practice Task
Build a small preference feature:
- Create
POST /api/preferences/theme. - Store theme in a secure cookie.
- Create
GET /api/preferences/theme. - Enable session.
- Store selected academic year in session.
- Read selected academic year from session.
Quick Recap
| Question | Answer |
|---|---|
| Cookies are stored where? | Browser |
| Session data is stored where? | Server |
| Enable session service? | AddSession() |
| Enable session middleware? | UseSession() |
| Cookie JavaScript protection? | HttpOnly |
| HTTPS-only cookie option? | Secure |
Q: What is the difference between cookies and session in ASP.NET Core?
Good Answer: "Cookies are small pieces of data stored in the browser and sent with requests. Session stores data on the server and usually keeps only a session id in a browser cookie. Cookies are useful for small preferences, while session is useful for temporary server-side user state. Sensitive authentication should not be implemented by manually storing usernames in cookies. Secure cookie options such as HttpOnly, Secure, SameSite, and expiration should be configured carefully."
Use ChatGPT, Claude, or Copilot to go deeper on Session and Cookies. Try these prompts:
"Explain cookies vs session in ASP.NET Core with examples.""How do I enable session in ASP.NET Core?""What do HttpOnly, Secure, and SameSite mean?""Why should I not store login usernames manually in cookies?"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.