# Django 5.2.8 documentation

# Hur man använder sessioner

Django ger fullt stöd för anonyma sessioner. Med sessionsramverket kan du lagra och hämta godtyckliga data per webbplatsbesökare. Det lagrar data på serversidan och abstraherar sändning och mottagning av cookies. Cookies innehåller ett sessions-ID - inte själva datan (såvida du inte använder cookie based backend).

## Möjliggörande av sessioner

Sessioner implementeras via en del av middleware.

Gör följande för att aktivera sessionsfunktionen:

- Redigera inställningen `MIDDLEWARE` och se till att den innehåller `'django.contrib.sessions.middleware.SessionMiddleware'`. Standardinställningen `settings.py` som skapades av `django-admin startproject` har `SessionMiddleware` aktiverad.

Om du inte vill använda sessioner kan du lika gärna ta bort raden `SessionMiddleware` från `MIDDLEWARE` och `'django.contrib.sessions'` från din `INSTALLED_APPS`. Det kommer att spara dig en liten bit av overhead.

## Konfigurera sessionsmotorn

Som standard lagrar Django sessioner i din databas (med hjälp av modellen `django.contrib.sessions.models.Session`). Även om detta är bekvämt, är det i vissa inställningar snabbare att lagra sessionsdata någon annanstans, så Django kan konfigureras för att lagra sessionsdata på ditt filsystem eller i din cache.

### Använda databasstödda sessioner

Om du vill använda en databasstödd session måste du lägga till `'django.contrib.sessions'` i din `INSTALLED_APPS`-inställning.

När du har konfigurerat din installation kör du `manage.py migrate` för att installera den enda databastabell som lagrar sessionsdata.

### Använda cachade sessioner

För bättre prestanda kanske du vill använda en cache-baserad sessionsbackend.

För att lagra sessionsdata med hjälp av Djangos cachesystem måste du först se till att du har konfigurerat din cache; se cache documentation för detaljer.

Varning

Du bör endast använda cache-baserade sessioner om du använder Memcached eller Redis cache-backend. Backend för lokal minnescache lagrar inte data tillräckligt länge för att vara ett bra val, och det går snabbare att använda fil- eller databassessioner direkt i stället för att skicka allt genom backend för fil- eller databascache. Dessutom är backend för lokal minnescache INTE säker för flera processer och är därför förmodligen inte ett bra val för produktionsmiljöer.

Om du har flera cacher definierade i `CACHES` kommer Django att använda standardcachen. För att använda en annan cache, ställ in `SESSION_CACHE_ALIAS` till namnet på den cachen.

När cachen är konfigurerad måste du välja mellan en databasstödd cache eller en icke-beständig cache.

Den cachelagrade databasbackenden (`cached_db`) använder en genomskrivningscache – sessionsskrivningar tillämpas på både databasen och cachen, i den ordningen. Om skrivningen till cacheminnet misslyckas hanteras och loggas undantaget via sessions logger, för att undvika att en annars lyckad skrivoperation misslyckas.

Sessionsläsningar använder cacheminnet eller databasen om data har hämtats från cacheminnet. För att använda denna backend, sätt `SESSION_ENGINE` till `"django.contrib.sessions.backends.cached_db"`, och följ konfigurationsinstruktionerna för använda sessioner med stöd av databas.

Cache-backend (`cache`) lagrar sessionsdata endast i din cache. Detta är snabbare eftersom det undviker databaspersistens, men du måste tänka på vad som händer när cachedata evakueras. Evakuering kan inträffa om cachen fylls eller cacheservern startas om, och det innebär att sessionsdata går förlorade, inklusive utloggning av användare. För att använda denna backend, ställ in `SESSION_ENGINE` till `"django.contrib.sessions.backends.cache"`.

Cachebackend kan göras beständig genom att använda en beständig cache, t.ex. Redis med lämplig konfiguration. Men om inte din cache definitivt är konfigurerad för tillräcklig uthållighet, välj den cachade databasbackend. På så sätt undviker du kantfall som orsakas av opålitlig datalagring i produktionen.

### Använda filbaserade sessioner

Om du vill använda filbaserade sessioner ställer du in `SESSION_ENGINE` till `"django.contrib.sessions.backends.file"`.

Du kanske också vill ange inställningen `SESSION_FILE_PATH` (som standard är utdata från `tempfile.gettempdir()`, troligen `/tmp`) för att styra var Django lagrar sessionsfiler. Se till att kontrollera att din webbserver har läs- och skrivbehörighet till denna plats.

### Använda cookie-baserade sessioner

För att använda cookies-baserade sessioner, sätt inställningen `SESSION_ENGINE` till `"django.contrib.sessions.backends.signed_cookies"`. Sessionsdata kommer att lagras med hjälp av Djangos verktyg för cryptographic signing och inställningen `SECRET_KEY`.

Observera

Vi rekommenderar att du låter `SESSION_COOKIE_HTTPONLY` vara inställd på `True` för att förhindra åtkomst till lagrade data från JavaScript.

Varning

Sessionsuppgifterna är signerade men inte krypterade

Vid användning av cookies backend kan sessionsdata läsas av klienten.

En MAC (Message Authentication Code) används för att skydda data mot ändringar av klienten, så att sessionsdata ogiltigförklaras när de manipuleras. Samma ogiltigförklaring sker om klienten som lagrar cookien (t.ex. din användares webbläsare) inte kan lagra alla sessionscookies och droppar data. Även om Django komprimerar data är det fortfarande fullt möjligt att överskrida den vanliga gränsen på 4096 byte per cookie.

Ingen färskhetsgaranti

Observera också att även om MAC kan garantera datans äkthet (att den genererats av din webbplats och inte av någon annan) och datans integritet (att allt finns där och är korrekt), kan den inte garantera färskhet, dvs. att du får tillbaka det senaste du skickade till klienten. Detta innebär att för vissa användningar av sessionsdata kan cookie-backend öppna upp för replay attacks. Till skillnad från andra sessionsbackends som registrerar varje session på serversidan och ogiltigförklarar den när en användare loggar ut, ogiltigförklaras inte cookie-baserade sessioner när en användare loggar ut. Om en angripare stjäl en användares cookie kan han eller hon alltså använda den cookien för att logga in som den användaren även om användaren loggar ut. Cookies kommer endast att upptäckas som ”föråldrade” om de är äldre än din `SESSION_COOKIE_AGE`.

Prestanda

Slutligen kan storleken på en cookie påverka hastigheten på din webbplats.

## Använda sessioner i vyer

När `SessionMiddleware` är aktiverat kommer varje `HttpRequest`-objekt - det första argumentet till en Django-vyfunktion - att ha ett `ession`-attribut, som är ett ordboksliknande objekt.

Du kan läsa den och skriva till `request.session` när som helst i din vy. Du kan redigera den flera gånger.

class backends.base.SessionBase

  Detta är basklassen för alla sessionsobjekt. Den har följande standardmetoder för ordböcker:

  __getitem__(key)

    Exempel: `fav_color = request.session['fav_color']`

  __setitem__(key, value)

    Exempel: `request.session['fav_color'] = 'blue'`

  __delitem__(key)

    Exempel: `del request.session['fav_color']`. Detta ger upphov till `KeyError` om den angivna `key` inte redan finns i sessionen.

  __contains__(key)

    Exempel: `'fav_color'' i request.session`

  get(key, default=None)
  aget(key, default=None)

    Asynkron version: `aget()`

    Exempel: `fav_color = request.session.get('fav_color', 'red')`

  aset(key, value)

    Exempel: `await request.session.aset('fav_color', 'red')`

  update(dict)
  aupdate(dict)

    Asynkron version: `aupdate()`

    Exempel: `request.session.update({'fav_color': 'red'})`

  pop(key, default=__not_given)
  apop(key, default=__not_given)

    Asynkron version: `apop()`

    Exempel: `fav_color = request.session.pop('fav_color', 'blue')`

  keys()
  akeys()

    Asynkron version: `akeys()`

  values()
  avalues()

    Asynkron version: `avalues()`

  has_key(key)
  ahas_key(key)

    Asynkron version: `ahas_key()`

  items()
  aitems()

    Asynkron version: `aitems()`

  setdefault()
  asetdefault()

    Asynkron version: `asetdefault()`

  clear()

  Den har också dessa metoder:

  flush()
  aflush()

    Asynkron version: `aflush()`

    Deletes the current session data from the session and deletes the session cookie. This is used if you want to ensure that the previous session data can’t be accessed again from the user’s browser (for example, the `django.contrib.auth.logout()` function calls it).

  set_test_cookie()
  aset_test_cookie()

    Asynkron version: `aset_test_cookie()`

    Ställer in en testcookie för att avgöra om användarens webbläsare stöder cookies. På grund av hur cookies fungerar kommer du inte att kunna testa detta förrän vid användarens nästa sidbegäran. Se Ställa in testcookies nedan för mer information.

  test_cookie_worked()
  atest_cookie_worked()

    Asynkron version: `senaste_cookie_arbetade()`

    Returnerar antingen `True` eller `False`, beroende på om användarens webbläsare accepterade testcookien. På grund av hur cookies fungerar måste du anropa `set_test_cookie()` eller `aset_test_cookie()` på en tidigare, separat sidbegäran. Se Ställa in testcookies nedan för mer information.

  delete_test_cookie()
  adelete_test_cookie()

    Asynkron version: `adelete_test_cookie()`

    Raderar testkakan. Använd den här för att städa upp efter dig.

  get_session_cookie_age()

    Returnerar värdet för inställningen `SESSION_COOKIE_AGE`. Detta kan åsidosättas i en anpassad sessionsbackend.

  set_expiry(value)
  aset_expiry(value)

    Asynkron version: `aset_expiry()`

    Ställer in utgångstiden för sessionen. Du kan ange ett antal olika värden:

    - Om `value` är ett heltal kommer sessionen att upphöra efter så många sekunder av inaktivitet. Om du till exempel säger `request.session.set_expiry(300)` kommer sessionen att upphöra om 5 minuter.

    - Om `value` är ett `datetime` eller `timedelta` objekt, kommer sessionen att upphöra vid det specifika datumet/tiden.

    - Om `värde` är `0` kommer användarens sessionscookie att upphöra att gälla när användarens webbläsare stängs.

    - Om `value` är `None` återgår sessionen till att använda den globala policyn för utgång av session.

    Läsning av en session betraktas inte som aktivitet när det gäller utgångsdatum. Sessionens utgångsdatum beräknas från den senaste gången sessionen modifierades.

  get_expiry_age()
  aget_expiry_age()

    Asynkron version: `aget_expiry_age()`

    Returnerar antalet sekunder tills den här sessionen löper ut. För sessioner utan anpassat utgångsdatum (eller de som är inställda på att upphöra när webbläsaren stängs) kommer detta att vara lika med `SESSION_COOKIE_AGE`.

    Denna funktion accepterar två valfria nyckelordsargument:

    - `modification`: senaste ändring av sessionen, som ett `datetime`-objekt. Standardvärdet är aktuell tid.

    - `expiry`: utgångsinformation för sessionen, som ett `datetime`-objekt, ett `int` (i sekunder) eller `None`. Standardvärdet är det värde som lagrats i sessionen av `set_expiry()`/`aset_expiry()`, om det finns ett sådant, eller `None`.

    Observera

    Denna metod används av sessionsbackends för att bestämma sessionens utgångsålder i sekunder när sessionen sparas. Den är egentligen inte avsedd för användning utanför detta sammanhang.

    I synnerhet, medan det är möjligt att bestämma den återstående livslängden för en session just när du har rätt `modifiering`-värde och `expiry` är inställt som ett `datetime`-objekt, där du har `modifiering`-värdet, är det mer enkelt att beräkna expiry för hand:

        expires_at = modification + timedelta(seconds=settings.SESSION_COOKIE_AGE)

  get_expiry_date()
  aget_expiry_date()

    Asynkron version: `aget_expiry_date()`

    Returnerar det datum då den här sessionen kommer att löpa ut. För sessioner som inte har något anpassat utgångsdatum (eller som är inställda på att upphöra när webbläsaren stängs) kommer detta att motsvara datumet `SESSION_COOKIE_AGE` seconds from now.

    Denna funktion accepterar samma nyckelordsargument som `get_expiry_age()`, och liknande anmärkningar om användning gäller.

  get_expire_at_browser_close()
  aget_expire_at_browser_close()

    Asynkron version: `aget_expire_at_browser_close()`

    Returnerar antingen `True` eller `False`, beroende på om användarens sessionscookie upphör att gälla när användarens webbläsare stängs.

  clear_expired()
  aclear_expired()

    Asynkron version: `aclear_expired()`

    Tar bort utgångna sessioner från sessionslagret. Denna klassmetod anropas av `clearsessions`.

  cycle_key()
  acycle_key()

    Asynkron version: `acycle_key()`

    Creates a new session key while retaining the current session data. `django.contrib.auth.login()` calls this method to mitigate against session fixation.

### Serialisering av session

Som standard serialiserar Django sessionsdata med hjälp av JSON. Du kan använda inställningen `SESSION_SERIALIZER` för att anpassa sessionens serialiseringsformat. Även med de försiktighetsåtgärder som beskrivs i Skriv din egen serializer rekommenderar vi starkt att du håller dig till JSON-serialisering särskilt om du använder cookie-backend.

Här är till exempel ett angreppsscenario om du använder `pickle` för att serialisera sessionsdata. Om du använder signed cookie session backend och `SECRET_KEY` (eller någon nyckel i `SECRET_KEY_FALLBACKS`) är känd av en angripare (det finns inte en inneboende sårbarhet i Django som skulle få den att läcka), kan angriparen infoga en sträng i deras session som, när den avplockas, kör godtycklig kod på servern. Tekniken för att göra detta är enkel och lätt tillgänglig på internet. Även om cookie-sessionslagringen signerar de cookie-lagrade data för att förhindra manipulering, eskalerar en `SECRET_KEY`-läcka omedelbart till en sårbarhet för fjärrkörning av kod.

#### Paketerade serialiserare

class serializers.JSONSerializer

  En wrapper runt JSON-serialisatorn från `django.core.signing`. Kan endast serialisera grundläggande datatyper.

  Eftersom JSON endast stöder strängnycklar bör du dessutom notera att användning av nycklar som inte är strängar i `request.session` inte kommer att fungera som förväntat:

      >>> # initial assignment
      >>> request.session[0] = "bar"
      >>> # subsequent requests following serialization & deserialization
      >>> # of session data
      >>> request.session[0]  # KeyError
      >>> request.session["0"]
      'bar'

  På samma sätt kan data som inte kan kodas i JSON, t.ex. icke-UTF8-bytes som `'\xd9'` (som ger upphov till `UnicodeDecodeError`), inte lagras.

  Se avsnittet Skriv din egen serializer för mer information om begränsningar för JSON-serialisering.

#### Skriv din egen serializer

Observera att `JSONSerializer` inte kan hantera godtyckliga Python-datatyper. Som ofta är fallet finns det en avvägning mellan bekvämlighet och säkerhet. Om du vill lagra mer avancerade datatyper, inklusive `datetime` och `Decimal` i JSON-backade sessioner, måste du skriva en anpassad serializer (eller konvertera sådana värden till ett JSON-serialiserbart objekt innan du lagrar dem i `request.session`). Medan serialisering av dessa värden ofta är okomplicerad (`DjangoJSONEncoder` kan vara till hjälp), är det mer bräckligt att skriva en avkodare som på ett tillförlitligt sätt kan få tillbaka samma sak som du lägger in. Till exempel riskerar du att returnera en `datetime` som faktiskt var en sträng som bara råkade vara i samma format som valts för `datetime`).

Din serializerklass måste implementera två metoder, `dumps(self, obj)` och `loads(self, data)`, för att serialisera respektive deserialisera ordlistan med sessionsdata.

### Riktlinjer för sessionsobjekt

- Använd normala Python-strängar som ordboksnycklar i `request.session`. Detta är mer av en konvention än en hård och fast regel.

- Nycklar i sessionsordlistan som börjar med ett understreck är reserverade för internt bruk av Django.

- Åsidosätt inte `request.session` med ett nytt objekt, och kom inte åt eller ställ in dess attribut. Använd det som en Python-ordbok.

### Exempel

Denna förenklade vy sätter variabeln `has_commented` till `True` efter att en användare har skrivit en kommentar. Den låter inte en användare posta en kommentar mer än en gång:

    def post_comment(request, new_comment):
        if request.session.get("has_commented", False):
            return HttpResponse("You've already commented.")
        c = comments.Comment(comment=new_comment)
        c.save()
        request.session["has_commented"] = True
        return HttpResponse("Thanks for your comment!")

Denna förenklade vy loggar in en ”medlem” på webbplatsen:

    def login(request):
        m = Member.objects.get(username=request.POST["username"])
        if m.check_password(request.POST["password"]):
            request.session["member_id"] = m.id
            return HttpResponse("You're logged in.")
        else:
            return HttpResponse("Your username and password didn't match.")

…Och den här loggar ut en medlem, enligt `login()` ovan:

    def logout(request):
        try:
            del request.session["member_id"]
        except KeyError:
            pass
        return HttpResponse("You're logged out.")

Standardfunktionen `django.contrib.auth.logout()` gör faktiskt lite mer än så för att förhindra oavsiktligt dataläckage. Den anropar `flush()`-metoden i `request.session`. Vi använder det här exemplet som en demonstration av hur man arbetar med sessionsobjekt, inte som en fullständig implementering av `logout()`.

## Inställning av testcookies

Som en bekvämlighet tillhandahåller Django ett sätt att testa om användarens webbläsare accepterar cookies. Anropa metoden `set_test_cookie()` i `request.session` i en vy, och anropa `test_cookie_worked()` i en efterföljande vy - inte i samma vyanrop.

Denna besvärliga uppdelning mellan `set_test_cookie()` och `test_cookie_worked()` är nödvändig på grund av hur cookies fungerar. När du ställer in en cookie kan du faktiskt inte säga om en webbläsare accepterade den förrän webbläsarens nästa begäran.

It’s good practice to use `delete_test_cookie()` to clean up after yourself. Do this after you’ve verified that the test cookie worked.

Här är ett typiskt exempel på användning:

    from django.http import HttpResponse
    from django.shortcuts import render

    def login(request):
        if request.method == "POST":
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
                return HttpResponse("You're logged in.")
            else:
                return HttpResponse("Please enable cookies and try again.")
        request.session.set_test_cookie()
        return render(request, "foo/login_form.html")

## Använda sessioner i stället för vyer

Observera

Exemplen i detta avsnitt importerar objektet `SessionStore` direkt från backend `django.contrib.sessions.backends.db`. I din egen kod bör du överväga att importera `SessionStore` från den sessionsmotor som anges av `SESSION_ENGINE`, enligt nedan:

    >>> from importlib import import_module
    >>> from django.conf import settings
    >>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore

Ett API finns tillgängligt för att manipulera sessionsdata utanför en vy:

    >>> from django.contrib.sessions.backends.db import SessionStore
    >>> s = SessionStore()
    >>> # stored as seconds since epoch since datetimes are not serializable in JSON.
    >>> s["last_login"] = 1376587691
    >>> s.create()
    >>> s.session_key
    '2b1189a188b44ad18c35e113ac6ceead'
    >>> s = SessionStore(session_key="2b1189a188b44ad18c35e113ac6ceead")
    >>> s["last_login"]
    1376587691

`SessionStore.create()` är avsedd att skapa en ny session (dvs. en som inte laddats från sessionslagret och med `session_key=None`). `save()` är avsedd att spara en befintlig session (dvs. en session som laddats från sessionslagret). Att anropa `save()` på en ny session kan också fungera men har en liten chans att generera en `session_key` som kolliderar med en befintlig. `create()` anropar `save()` och loopar tills en oanvänd `session_key` genereras.

Om du använder backend `django.contrib.sessions.backends.db` är varje session en vanlig Django-modell. Modellen `Session` definieras i django/contrib/sessions/models.py. Eftersom det är en normal modell kan du komma åt sessioner med hjälp av det normala Django-databas-API: et:

    >>> from django.contrib.sessions.models import Session
    >>> s = Session.objects.get(pk="2b1189a188b44ad18c35e113ac6ceead")
    >>> s.expire_date
    datetime.datetime(2005, 8, 20, 13, 35, 12)

Note that you’ll need to call `get_decoded()` to get the session dictionary. This is necessary because the dictionary is stored in an encoded format:

    >>> s.session_data
    'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
    >>> s.get_decoded()
    {'user_id': 42}

## När sessioner sparas

Som standard sparar Django bara i sessionsdatabasen när sessionen har ändrats, det vill säga om något av dess ordboksvärden har tilldelats eller tagits bort:

    # Session is modified.
    request.session["foo"] = "bar"

    # Session is modified.
    del request.session["foo"]

    # Session is modified.
    request.session["foo"] = {}

    # Gotcha: Session is NOT modified, because this alters
    # request.session['foo'] instead of request.session.
    request.session["foo"]["bar"] = "baz"

I det sista fallet i exemplet ovan kan vi uttryckligen tala om för sessionsobjektet att det har modifierats genom att ställa in attributet `modified` på sessionsobjektet:

    request.session.modified = True

För att ändra detta standardbeteende, sätt inställningen `SESSION_SAVE_EVERY_REQUEST` till `True`. När den är inställd på `True` kommer Django att spara sessionen i databasen vid varje enskild begäran.

Observera att sessionskakan endast skickas när en session har skapats eller ändrats. Om `SESSION_SAVE_EVERY_REQUEST` är `True` skickas sessionskakan vid varje förfrågan.

På samma sätt uppdateras ”upphör att gälla”-delen av en sessionskaka varje gång sessionskakan skickas.

Sessionen sparas inte om statuskoden för svaret är 500.

## Sessioner som varar hela webbläsaren jämfört med permanenta sessioner

Du kan styra om sessionsramverket ska använda sessioner med webbläsarlängd eller permanenta sessioner med inställningen `SESSION_EXPIRE_AT_BROWSER_CLOSE`.

Som standard är `SESSION_EXPIRE_AT_BROWSER_CLOSE` inställd på `False`, vilket innebär att sessionscookies lagras i användarnas webbläsare lika länge som `SESSION_COOKIE_AGE`. Använd detta om du inte vill att användarna ska behöva logga in varje gång de öppnar en webbläsare.

Om `SESSION_EXPIRE_AT_BROWSER_CLOSE` är inställd på `True`, kommer Django att använda cookies med webbläsarlängd - cookies som upphör att gälla så snart användaren stänger sin webbläsare. Använd detta om du vill att folk ska behöva logga in varje gång de öppnar en webbläsare.

Denna inställning är en global standardinställning och kan skrivas över per session genom att uttryckligen anropa `set_expiry()`-metoden för `request.session` enligt beskrivningen ovan i använda sessioner i vyer.

Observera

Vissa webbläsare (t.ex. Chrome) har inställningar som gör det möjligt för användare att fortsätta surfa efter att webbläsaren har stängts och öppnats igen. I vissa fall kan detta störa inställningen `SESSION_EXPIRE_AT_BROWSER_CLOSE` och förhindra att sessioner löper ut när webbläsaren stängs. Var medveten om detta när du testar Django-applikationer som har inställningen `SESSION_EXPIRE_AT_BROWSER_CLOSE` aktiverad.

## Rensning av sessionslagret

När användare skapar nya sessioner på din webbplats kan sessionsdata ackumuleras i din sessionsbutik. Om du använder databas-backend kommer databastabellen `django_session` att växa. Om du använder filbackend kommer din temporära katalog att innehålla ett ökande antal filer.

För att förstå detta problem, överväg vad som händer med databasens backend. När en användare loggar in lägger Django till en rad i databastabellen `django_session`. Django uppdaterar den här raden varje gång sessionsdata ändras. Om användaren loggar ut manuellt raderar Django raden. Men om användaren inte loggar ut raderas raden aldrig. En liknande process sker med filbackend.

Django tillhandahåller inte automatisk rensning av utgångna sessioner. Därför är det ditt jobb att rensa bort utgångna sessioner regelbundet. Django tillhandahåller ett kommando för upprensning för detta ändamål: `clearsessions`. Det rekommenderas att anropa detta kommando regelbundet, till exempel som ett dagligt cron-jobb.

Observera att cache-backend inte är sårbart för detta problem, eftersom cacher automatiskt raderar inaktuella data. Det är inte heller cookie-backend, eftersom sessionsdata lagras av användarnas webbläsare.

## Inställningar

Några Django-inställningar ger dig kontroll över sessionens beteende:

- `SESSION_CACHE_ALIAS`

- `SESSION_COOKIE_AGE`

- `SESSION_COOKIE_DOMAIN`

- `SESSION_COOKIE_HTTPONLY`

- `SESSION_COOKIE_NAME`

- `SESSION_COOKIE_PATH`

- `SESSION_COOKIE_SAMESITE`

- `SESSION_COOKIE_SECURE`

- `SESSION_ENGINE`

- `SESSION_EXPIRE_AT_BROWSER_CLOSE`

- `SESSION_FILE_PATH`

- `SESSION_SAVE_EVERY_REQUEST`

- `SESSION_SERIALIZER`

## Säkerhet för sessioner

Underdomäner inom en webbplats kan ställa in cookies på klienten för hela domänen. Detta gör sessionsfixering möjlig om cookies tillåts från underdomäner som inte kontrolleras av betrodda användare.

En angripare kan t.ex. logga in på `good.example.com` och få en giltig session för sitt konto. Om angriparen har kontroll över `bad.example.com` kan han eller hon använda den för att skicka sin sessionsnyckel till dig eftersom en underdomän tillåts sätta cookies på `*.example.com`. När du besöker `good.example.com` kommer du att vara inloggad som angriparen och kan oavsiktligt ange dina känsliga personuppgifter (t.ex. kreditkortsinformation) på angriparens konto.

En annan möjlig attack skulle vara om `good.example.com` sätter sin `SESSION_COOKIE_DOMAIN` till `"example.com"` vilket skulle leda till att sessionscookies från den webbplatsen skickas till `bad.example.com`.

## Tekniska detaljer

- Sessionsordlistan accepterar alla `json` serialiserbara värden när du använder `JSONSerializer`.

- Sessionsdata lagras i en databastabell med namnet `django_session`.

- Django skickar bara en cookie om det behövs. Om du inte anger några sessionsdata skickas ingen sessionskaka.

### Objektet `SessionStore`

När Django arbetar med sessioner internt använder Django ett sessionslagringsobjekt från motsvarande sessionsmotor. Enligt konvention heter klassen för sessionslagringsobjektet `SessionStore` och finns i den modul som anges av `SESSION_ENGINE`.

Alla underklasser till `SessionStore` som finns tillgängliga i Django implementerar följande metoder för datahantering:

- `exists()`

- `create()`

- `save()`

- `delete()`

- `load()`

- `clear_expired()`

Ett asynkront gränssnitt för dessa metoder tillhandahålls genom att de paketeras med `sync_to_async()`. De kan implementeras direkt om en asynkron implementation finns tillgänglig:

- `aexists()`

- `avsluta()`

- `asave()`

- `adelete()`

- `aload()`

- `aclear_expired()`

För att bygga en anpassad sessionsmotor eller för att anpassa en befintlig kan du skapa en ny klass som ärver från `SessionBase` eller någon annan befintlig `SessionStore`-klass.

Du kan utöka sessionsmotorerna, men att göra det med databasstödda sessionsmotorer kräver i allmänhet lite extra arbete (se nästa avsnitt för mer information).

## Utökning av databasstödda sessionsmotorer

Att skapa en anpassad databasstödd sessionsmotor som bygger på de som ingår i Django (nämligen `db` och `cached_db`) kan göras genom att ärva `AbstractBaseSession` och antingen `SessionStore`-klassen.

`AbstractBaseSession` och `BaseSessionManager` är importerbara från `django.contrib.sessions.base_session` så att de kan importeras utan att inkludera `django.contrib.sessions` i `INSTALLED_APPS`.

class base_session.AbstractBaseSession

  Den abstrakta basmodellen för sessionen.

  session_key

    Primär nyckel. Själva fältet kan innehålla upp till 40 tecken. Den nuvarande implementeringen genererar en sträng med 32 tecken (en slumpmässig sekvens av siffror och gemena ASCII-bokstäver).

  session_data

    En sträng som innehåller en kodad och serialiserad sessionsordbok.

  expire_date

    En datatid som anger när sessionen upphör att gälla.

    Utgångna sessioner är inte tillgängliga för en användare, men de kan fortfarande lagras i databasen tills kommandot `clearsessions` körs.

  classmethod get_session_store_class()

    Returnerar en session store-klass som ska användas med denna sessionsmodell.

  get_decoded()

    Returnerar avkodade sessionsdata.

    Avkodningen utförs av klassen session store.

Du kan också anpassa modellhanteraren genom att underklassa `BaseSessionManager`:

class base_session.BaseSessionManager
  encode(session_dict)

    Returnerar den angivna sessionsordboken serialiserad och kodad som en sträng.

    Kodningen utförs av klassen Session Store som är kopplad till en modellklass.

  save(session_key, session_dict, expire_date)

    Sparar sessionsdata för en angiven sessionsnyckel, eller raderar sessionen om data är tomma.

Anpassning av klasserna `SessionStore` uppnås genom att åsidosätta metoder och egenskaper som beskrivs nedan:

class backends.db.SessionStore

  Implementerar databasstödd sessionslagring.

  classmethod get_model_class()

    Skriv över den här metoden för att returnera en anpassad sessionsmodell om du behöver en.

  create_model_instance(data)

    Returnerar en ny instans av sessionsmodellobjektet, som representerar det aktuella sessionstillståndet.

    Genom att åsidosätta den här metoden kan du ändra data i sessionsmodellen innan de sparas i databasen.

class backends.cached_db.SessionStore

  Implementerar cachelagrad databasstödd sessionslagring.

  cache_key_prefix

    Ett prefix som läggs till en sessionsnyckel för att bygga upp en cache-nyckelsträng.

### Exempel

I exemplet nedan visas en anpassad databasstödd sessionsmotor som innehåller en extra databaskolumn för att lagra ett konto-ID (vilket ger möjlighet att söka i databasen efter alla aktiva sessioner för ett konto):

    from django.contrib.sessions.backends.db import SessionStore as DBStore
    from django.contrib.sessions.base_session import AbstractBaseSession
    from django.db import models

    class CustomSession(AbstractBaseSession):
        account_id = models.IntegerField(null=True, db_index=True)

        @classmethod
        def get_session_store_class(cls):
            return SessionStore

    class SessionStore(DBStore):
        @classmethod
        def get_model_class(cls):
            return CustomSession

        def create_model_instance(self, data):
            obj = super().create_model_instance(data)
            try:
                account_id = int(data.get("_auth_user_id"))
            except (ValueError, TypeError):
                account_id = None
            obj.account_id = account_id
            return obj

Om du migrerar från Djangos inbyggda `cached_db` sessionslagring till en anpassad lagring baserad på `cached_db`, bör du åsidosätta prefixet för cache-nyckeln för att förhindra en namnrymdskrock:

    class SessionStore(CachedDBStore):
        cache_key_prefix = "mysessions.custom_cached_db_backend"

        # ...

## Sessions-ID:n i webbadresser

Djangos sessionsramverk är helt och hållet, och enbart, cookie-baserat. Det faller inte tillbaka till att sätta sessions-ID i webbadresser som en sista utväg, som PHP gör. Detta är ett avsiktligt designbeslut. Det beteendet gör inte bara webbadresser fula, det gör din webbplats sårbar för stöld av sessions-ID via ”Referer”-rubriken.