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ällningensettings.py
som skapades avdjango-admin startproject
harSessionMiddleware
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.
Hantering och loggning av undantag vid skrivning till cacheminnet har lagts till.
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 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 tillKeyError
om den angivnakey
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')
Changed in Django 5.1:funktionen
aget()
har lagts till.
- aset(key, value)¶
- New in Django 5.1.
Exempel:
await request.session.aset('fav_color', 'red')
- update(dict)¶
- aupdate(dict)¶
Asynkron version:
aupdate()
Exempel:
request.session.update({'fav_color': 'red'})
Changed in Django 5.1:funktionen
aupdate()
har lagts till.
- pop(key, default=__not_given)¶
- apop(key, default=__not_given)¶
Asynkron version:
apop()
Exempel:
fav_color = request.session.pop('fav_color', 'blue')
Changed in Django 5.1:funktionen
apop()
har lagts till.
- keys()¶
- akeys()¶
Asynkron version:
akeys()
Changed in Django 5.1:funktionen
akeys()
har lagts till.
- values()¶
- avalues()¶
Asynkron version:
avalues()
Changed in Django 5.1:funktionen
avalues()
har lagts till.
- has_key(key)¶
- ahas_key(key)¶
Asynkron version:
ahas_key()
Changed in Django 5.1:funktionen
ahas_key()
har lagts till.
- items()¶
- aitems()¶
Asynkron version:
aitems()
Changed in Django 5.1:funktionen
aitems()
har lagts till.
- setdefault()¶
- asetdefault()¶
Asynkron version:
asetdefault()
Changed in Django 5.1:funktionen
asetdefault()
har lagts till.
- clear()¶
Den har också dessa metoder:
- flush()¶
- aflush()¶
Asynkron version:
aflush()
Raderar aktuella sessionsdata från sessionen och raderar sessionskakan. Detta används om du vill se till att de tidigare sessionsdata inte kan nås igen från användarens webbläsare (till exempel
django.contrib.auth.logout()
-funktionen anropar den).Changed in Django 5.1:funktionen
aflush()
har lagts till.
- 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.
Changed in Django 5.1:funktionen
aset_test_cookie()
har lagts till.
- test_cookie_worked()¶
- atest_cookie_worked()¶
Asynkron version:
senaste_cookie_arbetade()
Returnerar antingen
True
ellerFalse
, beroende på om användarens webbläsare accepterade testcookien. På grund av hur cookies fungerar måste du anropaset_test_cookie()
elleraset_test_cookie()
på en tidigare, separat sidbegäran. Se Ställa in testcookies nedan för mer information.Changed in Django 5.1:funktionen
atest_cookie_worked()
har lagts till.
- 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.
Changed in Django 5.1:funktionen
adelete_test_cookie()
har lagts till.
- 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ägerrequest.session.set_expiry(300)
kommer sessionen att upphöra om 5 minuter.Om
value
är ettdatetime
ellertimedelta
objekt, kommer sessionen att upphöra vid det specifika datumet/tiden.Om
värde
är0
kommer användarens sessionscookie att upphöra att gälla när användarens webbläsare stängs.Om
value
ärNone
å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.
Changed in Django 5.1:funktionen
aset_expiry()
har lagts till.
- 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 ettdatetime
-objekt. Standardvärdet är aktuell tid.expiry
: utgångsinformation för sessionen, som ettdatetime
-objekt, ettint
(i sekunder) ellerNone
. Standardvärdet är det värde som lagrats i sessionen avset_expiry()
/aset_expiry()
, om det finns ett sådant, ellerNone
.
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 ochexpiry
är inställt som ettdatetime
-objekt, där du harmodifiering
-värdet, är det mer enkelt att beräkna expiry för hand:expires_at = modification + timedelta(seconds=settings.SESSION_COOKIE_AGE)
Changed in Django 5.1:funktionen
aget_expiry_age()
har lagts till.
- 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.Changed in Django 5.1:funktionen
aget_expiry_date()
har lagts till.
- get_expire_at_browser_close()¶
- aget_expire_at_browser_close()¶
Asynkron version:
aget_expire_at_browser_close()
Returnerar antingen
True
ellerFalse
, beroende på om användarens sessionscookie upphör att gälla när användarens webbläsare stängs.Changed in Django 5.1:funktionen
aget_expire_at_browser_close()
har lagts till.
- clear_expired()¶
- aclear_expired()¶
Asynkron version:
aclear_expired()
Tar bort utgångna sessioner från sessionslagret. Denna klassmetod anropas av
clearsessions
.Changed in Django 5.1:funktionen
aclear_expired()
har lagts till.
- cycle_key()¶
- acycle_key()¶
Asynkron version:
acycle_key()
Skapar en ny sessionsnyckel samtidigt som de aktuella sessionsdata behålls.
django.contrib.auth.login()
anropar denna metod för att motverka sessionsfixering.Changed in Django 5.1:funktionen
acycle_key()
har lagts till.
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 tillUnicodeDecodeError
), 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()
.
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)
Observera att du måste anropa get_decoded()
för att hämta sessionsordboken. Detta är nödvändigt eftersom ordlistan lagras i ett kodat 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:
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änderJSONSerializer
.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:
existerar()`
skapa()`
save()`
delete()`
load()`
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()`
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).
metoderna aexists()
, acreate()
, asave()
, adelete()
, aload()
och aclear_expired()
har lagts till.
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.