801. Cookies w Django. Jak wygląda obsługa ciastek w Django?

Cookie / ciastko:
    - ciąg znaków, który zawiera klucz i wartość (oraz opcjonalne parametry, jak czas wygaśnięcia, ścieżka czy domena).
    Odpowiedź serwera (nagłówek):
    - Set-Cookie: user_id=42; Max-Age=3600; Path=/; Domain=example.com; Secure; HttpOnly; SameSite=Lax
    Klient / zapytanie przeglądarki (nagłówek):
    - Cookie: sessionid=abc123

Rodzaje ciastek
    Ciasteczka sesyjne (session cookies):
        Przechowywane tylko w pamięci przeglądarki.
        Usuwane po zamknięciu przeglądarki.

    Ciasteczka trwałe (persistent cookies):
        Mają ustawiony czas wygaśnięcia (Expires lub Max-Age).
        Przechowywane na dysku użytkownika i dostępne między sesjami przeglądarki.

    Ciasteczka stron trzecich (third-party cookies):
        Ustawiane przez domeny inne niż ta, którą użytkownik odwiedza (np. ciasteczka reklamowe).
    W Django obsługa ciasteczek jest bardzo prosta i zintegrowana z obiektami HttpRequest i HttpResponse.
    Podstawy obsługi ciasteczek w Django:
        a) Odczytywanie ciasteczek
           Ciasteczka w Django można odczytywać z obiektu żądania (request) za pomocą słownika request.COOKIES
        b) Ustawianie ciasteczek
           Ciasteczka ustawia się, modyfikując obiekt HttpResponse za pomocą metody set_cookie().
        c) Usuwanie ciasteczek
           Aby usunąć ciasteczko, używamy metody delete_cookie().
    
    
    Przykład kompletnego cyklu pracy z ciasteczkami:
        from django.http import HttpResponse
    
        # Ustawianie ciasteczka
        def set_cookie(request):
            response = HttpResponse('Ustawiam ciasteczko "username".')
            response.set_cookie('username', 'JohnDoe', max_age=3600)  # 1 godzina
            return response
    
        # Odczyt ciasteczka
        def get_cookie(request):
            username = request.COOKIES.get('username', 'Gość')  # Domyślna wartość: "Gość"
            return HttpResponse(f'Witaj, {username}!')
    
        # Usuwanie ciasteczka
        def delete_cookie(request):
            response = HttpResponse('Usuwam ciasteczko "username".')
            response.delete_cookie('username')
            return response
    
    
    Kluczowe aspekty bezpieczeństwa przy obsłudze ciasteczek:
    
    a) Secure: Przesyłanie ciasteczek tylko przez HTTPS
        - Parametr secure=True wymusza, że ciasteczko będzie przesyłane tylko przez szyfrowane połączenia HTTPS.
        - response.set_cookie('username', 'JohnDoe', secure=True)
    
    b) HttpOnly: Ograniczenie dostępu do ciasteczka
        - Ustawienie httponly=True oznacza, że ciasteczko nie będzie dostępne z poziomu JavaScript (chroni przed atakami XSS).
        - response.set_cookie('username', 'JohnDoe', httponly=True)
    
    c) SameSite: Ochrona przed atakami CSRF
        - Parametr samesite kontroluje, czy ciasteczko może być wysyłane w żądaniach z innych domen.
        - Strict: Ciasteczko wysyłane tylko w żądaniach z tej samej domeny.
        - Lax: Ciasteczko wysyłane w żądaniach GET z innych domen (domyślne w Django od wersji 3.1).
        - response.set_cookie('username', 'JohnDoe', samesite='Strict')
    
    
    Konfiguracja ciasteczek w settings.py:
        SESSION_COOKIE_SECURE = True       # Wymusza HTTPS dla ciasteczek sesji
        SESSION_COOKIE_HTTPONLY = True     # Chroni ciasteczka sesji przed dostępem z JavaScript
        SESSION_COOKIE_SAMESITE = 'Lax'    # Ochrona ciasteczek sesji przed CSRF
        CSRF_COOKIE_SECURE = True          # Wymusza HTTPS dla ciasteczka CSRF
        CSRF_COOKIE_HTTPONLY = False       # Ciasteczko CSRF musi być dostępne dla JavaScript
        CSRF_COOKIE_SAMESITE = 'Lax'       # Ochrona ciasteczka CSRF
    

    Kiedy używać ciasteczek w Django?
        a) Idealne przypadki użycia:
            Dane, które muszą być dostępne po stronie klienta:
                Preferencje użytkownika (np. język, motyw, ustawienia interfejsu).
                Identyfikatory unikalne dla użytkownika (np. csrftoken).
            Dane, które nie są krytyczne z punktu widzenia bezpieczeństwa.
    
        b) Nieodpowiednie przypadki użycia:
            Nie przechowuj poufnych informacji w ciasteczkach (np. haseł, tokenów dostępu).
            Do zarządzania stanem użytkownika (np. logowanie) lepiej używać sesji Django (request.session).