Średni · lekcja 13

Sesje i ciasteczka w ASP.NET Core

HTTP jest z natury "bezstanowy" — serwer normalnie NIE pamięta niczego między jednym żądaniem a drugim, każde żądanie traktowane jest jak od zupełnie nowego, nieznajomego użytkownika. Ale przecież aplikacje muszą pamiętać, że ktoś jest zalogowany, co ma w kosz...

Zacznij tutaj

Po co się tego uczymy?

HTTP jest z natury "bezstanowy" — serwer normalnie NIE pamięta niczego między jednym żądaniem a drugim, każde żądanie traktowane jest jak od zupełnie nowego, nieznajomego użytkownika. Ale przecież aplikacje muszą pamiętać, że ktoś jest zalogowany, co ma w koszyku zakupowym, jakie wybrał ustawienia — dokładnie ten sam problem, który w dziale PHP rozwiązywały sesje i ciasteczka. Ta lekcja pokazuje, jak identyczny mechanizm działa w ASP.NET Core.

Wprowadzenie

Teoria

Ciasteczka (cookies) to małe fragmenty danych zapisywane PRZEZ SERWER w przeglądarce użytkownika — przeglądarka automatycznie odsyła je z powrotem do serwera przy KAŻDYM kolejnym żądaniu do tej samej domeny. To fundamentalny mechanizm, dzięki któremu serwer w ogóle może "rozpoznać" powracającego użytkownika. W ASP.NET Core: Response.Cookies.Append("klucz", "wartosc", opcje) zapisuje ciasteczko, Request.Cookies["klucz"] odczytuje jego wartość (zwraca null, jeśli nie istnieje), Response.Cookies.Delete("klucz") usuwa.

Sesje (session) to mechanizm WYŻSZEGO poziomu, zbudowany NA BAZIE ciasteczek: serwer generuje unikalny identyfikator sesji, zapisuje go w JEDNYM ciasteczku (.AspNetCore.Session), a WSZYSTKIE faktyczne dane (mogące być znacznie większe i bardziej złożone niż w zwykłym ciasteczku) trzyma po stronie SERWERA, powiązane z tym identyfikatorem. Przeglądarka "nie widzi" samych danych sesji — widzi tylko krótki identyfikator, który za każdym razem odsyła z powrotem.

Konfiguracja sesji wymaga dwóch kroków w Program.cs: rejestracji usługi (builder.Services.AddDistributedMemoryCache() + builder.Services.AddSession()) i włączenia middleware (app.UseSession(), wywołane PRZED app.MapRazorPages()/app.MapControllers() — kolejność ma znaczenie!). Dostęp do sesji w kodzie strony/kontrolera: HttpContext.Session.SetString("klucz", wartosc) / GetString("klucz") (dla liczb: SetInt32/GetInt32) — sesja natywnie obsługuje TYLKO stringi i liczby całkowite; dla bardziej złożonych obiektów trzeba je zserializować (np. do JSON) przed zapisem.

MechanizmGdzie przechowywane daneTypowe zastosowanie
Ciasteczkow przeglądarce użytkownikamałe, długotrwałe dane: "zapamiętaj mnie", preferowany język, zgoda na cookies
Sesjana serwerze (ciasteczko trzyma tylko identyfikator)dane tymczasowe, ważne TYLKO podczas jednej wizyty: zawartość koszyka, stan logowania

Czas życia. Ciasteczko może mieć ustawioną datę wygaśnięcia (CookieOptions { Expires = DateTimeOffset.Now.AddDays(30) }) — przetrwa nawet zamknięcie przeglądarki. Sesja domyślnie wygasa po określonym czasie BEZCZYNNOŚCI (options.IdleTimeout = TimeSpan.FromMinutes(20)) — jeśli użytkownik nic nie robi przez ten czas, dane sesji są tracone.

RODO i zgoda na cookies. W prawdziwych, publicznych aplikacjach webowych w Unii Europejskiej użycie ciasteczek (poza absolutnie niezbędnymi do działania strony) wymaga jawnej zgody użytkownika — stąd powszechne banery "Ta strona używa plików cookie" na niemal każdej stronie internetowej.

Zobacz zależności

Schemat

Pierwsza wizyta użytkownika
        │
        ▼
Serwer tworzy sesję, generuje ID (np. "a1b2c3...")
        │
        ▼
Response: Set-Cookie: .AspNetCore.Session=a1b2c3...
        │
        ▼
Przeglądarka zapisuje ciasteczko
        │
        │  (kolejne żądanie, np. "Dodaj do koszyka")
        ▼
Request: Cookie: .AspNetCore.Session=a1b2c3...
        │
        ▼
Serwer odczytuje ID sesji z ciasteczka
        │
        ▼
HttpContext.Session → dane TEJ konkretnej sesji (przechowywane na serwerze)
        │
        ▼
HttpContext.Session.SetString("koszyk", "...") - zapis
HttpContext.Session.GetString("koszyk")        - odczyt przy kolejnym żądaniu

Połącz z praktyką

Przykład z życia

Koszyk zakupowy w sklepie internetowym pamięta dodane produkty przez cały czas przeglądania sklepu (dzięki sesji), a osobne ciasteczko może zapamiętać, że użytkownik już RAZ zaakceptował politykę prywatności, żeby baner z pytaniem o zgodę nie pojawiał się przy KAŻDEJ kolejnej wizycie przez najbliższe 30 dni.