Django proporciona soporte completo para sesiones anónimas. El marco de la sesión le permite almacenar y recuperar datos arbitrarios por visitante del sitio. Almacena datos en el lado del servidor y abstrae el envío y la recepción de cookies. Las cookies contienen un ID de sesión, no los datos en sí (a menos que esté utilizando el backend basado en cookies).

Habilitación de sesiones

Las sesiones se implementan a través de una pieza de middleware.

Para habilitar la funcionalidad de la sesión, haga lo siguiente:

  • Edite el MIDDLEWARE ajuste y asegúrese de que contenga 'django.contrib.sessions.middleware.SessionMiddleware'. El valor por defecto settings.py creado por django-admin startproject tiene SessionMiddleware activado.

Si no desea utilizar sesiones, también puede eliminar el SessionMiddleware línea de MIDDLEWARE y 'django.contrib.sessions' de tu INSTALLED_APPS. Le ahorrará un poco de gastos generales.

Configurar el motor de sesión

Por defecto, Django almacena sesiones en su base de datos (usando el modelo django.contrib.sessions.models.Session). Aunque esto es conveniente, en algunas configuraciones es más rápido almacenar datos de sesión en otro lugar, por lo que Django puede configurarse para almacenar datos de sesión en su sistema de archivos o en su caché.

Usar sesiones respaldadas por bases de datos

Si desea utilizar una sesión respaldada por una base de datos, debe agregar 'django.contrib.sessions' para usted INSTALLED_APPS configuración.

Una vez que haya configurado su instalación, ejecute manage.py migrate para instalar la tabla de base de datos única que almacena los datos de la sesión.

Usar sesiones en caché

Para un mejor rendimiento, es posible que desee utilizar un backend de sesión basado en caché.

Para almacenar datos de sesión usando el sistema de caché de Django, primero deberá asegurarse de haber configurado su caché; ver el documentación de caché para detalles.

Advertencia

Solo debe usar sesiones basadas en caché si está utilizando el backend de caché Memcached. El backend de caché de memoria local no retiene los datos el tiempo suficiente para ser una buena opción, y será más rápido usar sesiones de archivo o base de datos directamente en lugar de enviar todo a través de los backends de caché de archivo o base de datos. Además, el backend de caché de memoria local NO es seguro para múltiples procesos, por lo que probablemente no sea una buena opción para entornos de producción.

Si tiene varias cachés definidas en CACHES, Django usará la caché predeterminada. Para usar otra caché, configure SESSION_CACHE_ALIAS al nombre de ese caché.

Una vez que su caché está configurada, tiene dos opciones sobre cómo almacenar datos en la caché:

  • Colocar SESSION_ENGINE para "django.contrib.sessions.backends.cache" para una tienda de sesión de almacenamiento en caché simple. Los datos de la sesión se almacenarán directamente en su caché. Sin embargo, es posible que los datos de la sesión no sean persistentes: los datos almacenados en caché se pueden desalojar si se llena o si se reinicia el servidor de caché.
  • Para datos almacenados en caché persistentes, establezca SESSION_ENGINE para "django.contrib.sessions.backends.cached_db". Esto usa una caché de escritura simultánea: cada escritura en la caché también se escribirá en la base de datos. Las lecturas de sesión solo usan la base de datos si los datos aún no están en la caché.

Ambos almacenes de sesiones son bastante rápidos, pero la caché simple es más rápida porque ignora la persistencia. En la mayoría de los casos, cached_db El backend será lo suficientemente rápido, pero si necesita ese último rendimiento y está dispuesto a permitir que los datos de la sesión se eliminen de vez en cuando, el cache backend es para ti.

Si usa el cached_db backend de sesión, también debe seguir las instrucciones de configuración para el uso de sesiones respaldadas por la base de datos.

Usar sesiones basadas en archivos

Para usar sesiones basadas en archivos, configure el SESSION_ENGINE ajuste a "django.contrib.sessions.backends.file".

Es posible que también desee configurar el SESSION_FILE_PATH ajuste (que por defecto sale de tempfile.gettempdir(), más probable /tmp) para controlar dónde almacena Django los archivos de sesión. Asegúrese de verificar que su servidor web tenga permisos para leer y escribir en esta ubicación.

Usar sesiones basadas en cookies

Para utilizar sesiones basadas en cookies, configure el SESSION_ENGINE ajuste a "django.contrib.sessions.backends.signed_cookies". Los datos de la sesión se almacenarán utilizando las herramientas de Django para firma criptográfica y el SECRET_KEY configuración.

Nota

Se recomienda dejar el SESSION_COOKIE_HTTPONLY puesta en True para evitar el acceso a los datos almacenados desde JavaScript.

Advertencia

Si el SECRET_KEY no se mantiene en secreto y está utilizando el PickleSerializer, esto puede llevar a la ejecución de código remoto arbitrario.

Un atacante en posesión del SECRET_KEY no solo puede generar datos de sesión falsificados, en los que su sitio confiará, sino que también puede ejecutar código arbitrario de forma remota, ya que los datos se serializan usando pickle.

Si utiliza sesiones basadas en cookies, preste especial atención a que su clave secreta siempre se mantenga completamente secreta, para cualquier sistema que pueda ser accesible de forma remota.

Los datos de la sesión están firmados pero no cifrados

Al utilizar el backend de cookies, el cliente puede leer los datos de la sesión.

Se utiliza un MAC (código de autenticación de mensajes) para proteger los datos contra cambios por parte del cliente, de modo que los datos de la sesión se invaliden cuando se manipulan. La misma invalidación ocurre si el cliente que almacena la cookie (por ejemplo, el navegador de su usuario) no puede almacenar toda la cookie de sesión y descarta datos. A pesar de que Django comprime los datos, todavía es completamente posible exceder el límite común de 4096 bytes por galleta.

Sin garantía de frescura

Tenga en cuenta también que, si bien el MAC puede garantizar la autenticidad de los datos (que fueron generados por su sitio y no por otra persona), y la integridad de los datos (que están todos ahí y son correctos), no puede garantizar la frescura, es decir, que se le devuelve lo último que le envió al cliente. Esto significa que para algunos usos de los datos de la sesión, el backend de la cookie puede abrirle repetición de ataques. A diferencia de otros backends de sesión que mantienen un registro del lado del servidor de cada sesión y lo invalidan cuando un usuario cierra la sesión, las sesiones basadas en cookies no se invalidan cuando un usuario cierra la sesión. Por lo tanto, si un atacante roba la cookie de un usuario, puede usar esa cookie para iniciar sesión como ese usuario incluso si el usuario cierra la sesión. Las cookies solo se detectarán como “obsoletas” si son más antiguas que su SESSION_COOKIE_AGE.

Rendimiento

Finalmente, el tamaño de una cookie puede tener un impacto en la velocidad de su sitio.

Usar sesiones en vistas

Cuando SessionMiddleware está activado, cada HttpRequest objeto, el primer argumento para cualquier función de vista de Django, tendrá una session atributo, que es un objeto similar a un diccionario.

Puedes leerlo y escribir a request.session en cualquier punto de su vista. Puede editarlo varias veces.

class backends.base.SessionBase

Esta es la clase base para todos los objetos de sesión. Tiene los siguientes métodos de diccionario estándar:

__getitem__(key)

Ejemplo: fav_color = request.session['fav_color']

__setitem__(key, value)

Ejemplo: request.session['fav_color'] = 'blue'

__delitem__(key)

Ejemplo: del request.session['fav_color']. Esto plantea KeyError si el dado key aún no está en la sesión.

__contains__(key)

Ejemplo: 'fav_color' in request.session

get(key, default=None)

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

pop(key, default=__not_given)

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

keys()
items()
setdefault()
clear()

También tiene estos métodos:

flush()

Elimina los datos de la sesión actual de la sesión y elimina la cookie de sesión. Se utiliza si desea asegurarse de que no se pueda volver a acceder a los datos de la sesión anterior desde el navegador del usuario (por ejemplo, el django.contrib.auth.logout() la función lo llama).

set_test_cookie()

Establece una cookie de prueba para determinar si el navegador del usuario admite cookies. Debido a la forma en que funcionan las cookies, no podrá probar esto hasta que el usuario solicite la página siguiente. Consulte Configuración de cookies de prueba a continuación para obtener más información.

test_cookie_worked()

Devuelve True o False, dependiendo de si el navegador del usuario aceptó la cookie de prueba. Debido a la forma en que funcionan las cookies, tendrá que llamar set_test_cookie() en una solicitud de página separada anterior. Consulte Configuración de cookies de prueba a continuación para obtener más información.

delete_test_cookie()

Elimina la cookie de prueba. Use esto para limpiar después de usted mismo.

get_session_cookie_age()

Devuelve la antigüedad de las cookies de sesión, en segundos. Predeterminado a SESSION_COOKIE_AGE.

set_expiry(value)

Establece el tiempo de vencimiento de la sesión. Puede pasar varios valores diferentes:

  • Si value es un número entero, la sesión caducará después de esa cantidad de segundos de inactividad. Por ejemplo, llamando request.session.set_expiry(300) haría que la sesión caducara en 5 minutos.
  • Si value es un datetime o timedelta objeto, la sesión caducará en esa fecha / hora específicas. Tenga en cuenta que datetime y timedelta Los valores solo son serializables si está utilizando el PickleSerializer.
  • Si value es 0, la cookie de sesión del usuario caducará cuando se cierre el navegador web del usuario.
  • Si value es None, la sesión vuelve a utilizar la política de caducidad de sesión global.

La lectura de una sesión no se considera actividad a efectos de caducidad. La caducidad de la sesión se calcula a partir de la última vez que se realizó la sesión. modificado.

get_expiry_age()

Devuelve el número de segundos hasta que expire esta sesión. Para las sesiones sin vencimiento personalizado (o aquellas que vencen al cerrar el navegador), esto será igual SESSION_COOKIE_AGE.

Esta función acepta dos argumentos de palabras clave opcionales:

  • modification: última modificación de la sesión, como datetime objeto. Predeterminado a la hora actual.
  • expiry: información de caducidad de la sesión, como datetime objeto, un int (en segundos), o None. Por defecto, el valor almacenado en la sesión por set_expiry(), si hay uno, o None.
get_expiry_date()

Devuelve la fecha de caducidad de esta sesión. Para las sesiones sin vencimiento personalizado (o aquellas que vencen al cerrar el navegador), esto será igual a la fecha SESSION_COOKIE_AGE segundos a partir de ahora.

Esta función acepta los mismos argumentos de palabras clave que get_expiry_age().

get_expire_at_browser_close()

Devuelve True o False, dependiendo de si la cookie de sesión del usuario caducará cuando se cierre el navegador web del usuario.

clear_expired()

Elimina las sesiones caducadas del almacén de sesiones. Este método de clase es llamado por clearsessions.

cycle_key()

Crea una nueva clave de sesión conservando los datos de la sesión actual. django.contrib.auth.login() llama a este método para mitigar la fijación de sesiones.

Serialización de sesiones

De forma predeterminada, Django serializa los datos de la sesión usando JSON. Puedes usar el SESSION_SERIALIZER configuración para personalizar el formato de serialización de la sesión. Incluso con las advertencias descritas en Escribe tu propio serializador, recomendamos encarecidamente seguir con la serialización JSON especialmente si está utilizando el backend de cookies.

Por ejemplo, aquí hay un escenario de ataque si usa pickle para serializar los datos de la sesión. Si está usando el backend de sesión de cookies firmado y SECRET_KEY es conocido por un atacante (no hay una vulnerabilidad inherente en Django que pueda causar una fuga), el atacante podría insertar una cadena en su sesión que, cuando se elimina, ejecuta código arbitrario en el servidor. La técnica para hacerlo es simple y está fácilmente disponible en Internet. Aunque el almacenamiento de la sesión de cookies firma los datos almacenados en las cookies para evitar alteraciones, un SECRET_KEY la fuga se convierte inmediatamente en una vulnerabilidad de ejecución remota de código.

Serializadores incluidos

class serializers.JSONSerializer

Un contenedor alrededor del serializador JSON de django.core.signing. Solo se pueden serializar tipos de datos básicos.

Además, como JSON solo admite claves de cadena, tenga en cuenta que el uso claves que no son cadenas en request.session no funcionará como se esperaba:

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

Del mismo modo, los datos que no se pueden codificar en JSON, como bytes que no son UTF8 como 'xd9' (que eleva UnicodeDecodeError), no se puede almacenar.

Ver el Escribe tu propio serializador sección para obtener más detalles sobre las limitaciones de la serialización JSON.

class serializers.PickleSerializer

Admite objetos Python arbitrarios, pero, como se describió anteriormente, puede provocar una vulnerabilidad de ejecución remota de código si SECRET_KEY llega a ser conocido por un atacante.

Escribe tu propio serializador

Tenga en cuenta que a diferencia de PickleSerializer, los JSONSerializer no puede manejar tipos de datos de Python arbitrarios. Como suele ocurrir, existe un equilibrio entre comodidad y seguridad. Si desea almacenar tipos de datos más avanzados, incluidos datetime y Decimal en sesiones respaldadas por JSON, deberá escribir un serializador personalizado (o convertir dichos valores en un objeto serializable JSON antes de almacenarlos en request.session). Si bien la serialización de estos valores suele ser sencilla (DjangoJSONEncoder puede ser útil), escribir un decodificador que pueda recuperar de manera confiable lo mismo que colocó es más frágil. Por ejemplo, corre el riesgo de devolver un datetime que en realidad era una cadena que estaba en el mismo formato elegido para datetimes).

Su clase de serializador debe implementar dos métodos, dumps(self, obj) y loads(self, data), para serializar y deserializar el diccionario de datos de sesión, respectivamente.

Directrices de objeto de sesión

  • Utilice cadenas de Python normales como claves de diccionario en request.session. Esto es más una convención que una regla estricta.
  • Las claves del diccionario de sesión que comienzan con un guión bajo están reservadas para uso interno de Django.
  • No anule request.session con un nuevo objeto y no acceda ni establezca sus atributos. Úselo como un diccionario de Python.

Ejemplos de

Esta visión simplista establece un has_commented variable a True después de que un usuario publique un comentario. No permite que un usuario publique un comentario más de una vez:

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!')

Esta vista simplista registra en un “miembro” del sitio:

def login(request):
    m = Member.objects.get(username=request.POST['username'])
    if m.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.")

… Y este cierra la sesión de un miembro, según login() encima:

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

El estandar django.contrib.auth.logout() La función en realidad hace un poco más que esto para evitar la fuga de datos inadvertida. Llama al flush() método de request.session. Estamos usando este ejemplo como una demostración de cómo trabajar con objetos de sesión, no como un logout() implementación.

Configuración de cookies de prueba

Para su comodidad, Django proporciona una forma de probar si el navegador del usuario acepta cookies. Llama a set_test_cookie() método de request.session en una vista, y llame test_cookie_worked() en una vista posterior, no en la misma llamada de vista.

Esta incómoda división entre set_test_cookie() y test_cookie_worked() es necesario debido a la forma en que funcionan las cookies. Cuando configura una cookie, en realidad no puede saber si un navegador la aceptó hasta la próxima solicitud del navegador.

Es una buena práctica usar delete_test_cookie() para limpiar después de ti mismo. Haga esto después de haber verificado que la cookie de prueba funcionó.

A continuación, se muestra un ejemplo de uso típico:

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')

Usar sesiones fuera de las vistas

Nota

Los ejemplos de esta sección importan SessionStore objeto directamente desde el django.contrib.sessions.backends.db backend. En su propio código, debería considerar importar SessionStore desde el motor de sesión designado por SESSION_ENGINE, como a continuación:

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

Hay una API disponible para manipular los datos de la sesión fuera de una vista:

>>> 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() está diseñado para crear una nueva sesión (es decir, una no cargada desde el almacén de sesiones y con session_key=None). save() está diseñado para guardar una sesión existente (es decir, una cargada desde el almacén de sesiones). Vocación save() en una nueva sesión también puede funcionar, pero tiene una pequeña posibilidad de generar una session_key que choca con uno existente. create() llamadas save() y bucles hasta que no se use session_key es generado.

Si está usando el django.contrib.sessions.backends.db backend, cada sesión es un modelo Django normal. los Session el modelo se define en django/contrib/sessions/models.py. Debido a que es un modelo normal, puede acceder a las sesiones utilizando la API normal de la base de datos de Django:

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

Tenga en cuenta que deberá llamar get_decoded() para obtener el diccionario de la sesión. Esto es necesario porque el diccionario se almacena en un formato codificado:

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

Cuando se guardan las sesiones

De forma predeterminada, Django solo guarda en la base de datos de la sesión cuando la sesión ha sido modificada, es decir, si alguno de sus valores de diccionario ha sido asignado o eliminado:

# 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'

En el último caso del ejemplo anterior, podemos decirle al objeto de sesión explícitamente que ha sido modificado estableciendo el modified atributo en el objeto de sesión:

request.session.modified = True

Para cambiar este comportamiento predeterminado, configure el SESSION_SAVE_EVERY_REQUEST ajuste a True. Cuando se establece en True, Django guardará la sesión en la base de datos en cada solicitud.

Tenga en cuenta que la cookie de sesión solo se envía cuando se ha creado o modificado una sesión. Si SESSION_SAVE_EVERY_REQUEST es True, la cookie de sesión se enviará con cada solicitud.

Del mismo modo, el expires parte de una cookie de sesión se actualiza cada vez que se envía la cookie de sesión.

La sesión no se guarda si el código de estado de la respuesta es 500.

Sesiones de duración del navegador frente a sesiones persistentes

Puede controlar si el marco de la sesión utiliza sesiones de duración del navegador frente a sesiones persistentes con el SESSION_EXPIRE_AT_BROWSER_CLOSE configuración.

Por defecto, SESSION_EXPIRE_AT_BROWSER_CLOSE se establece en False, lo que significa que las cookies de sesión se almacenarán en los navegadores de los usuarios durante el tiempo que SESSION_COOKIE_AGE. Úselo si no desea que las personas tengan que iniciar sesión cada vez que abren un navegador.

Si SESSION_EXPIRE_AT_BROWSER_CLOSE se establece en True, Django utilizará cookies del tamaño del navegador, cookies que caducan tan pronto como el usuario cierra su navegador. Use esto si desea que las personas tengan que iniciar sesión cada vez que abren un navegador.

Esta configuración es un valor predeterminado global y se puede sobrescribir en un nivel por sesión llamando explícitamente al set_expiry() método de request.session como se describe anteriormente en el uso de sesiones en vistas.

Nota

Algunos navegadores (Chrome, por ejemplo) proporcionan configuraciones que permiten a los usuarios continuar navegando sesiones después de cerrar y volver a abrir el navegador. En algunos casos, esto puede interferir con la SESSION_EXPIRE_AT_BROWSER_CLOSE configurar y evitar que las sesiones caduquen al cerrar el navegador. Tenga esto en cuenta al probar aplicaciones de Django que tienen la SESSION_EXPIRE_AT_BROWSER_CLOSE ajuste habilitado.

Borrar la tienda de sesiones

A medida que los usuarios crean nuevas sesiones en su sitio web, los datos de la sesión pueden acumularse en su tienda de sesiones. Si está utilizando el backend de la base de datos, django_session La tabla de la base de datos crecerá. Si está utilizando el backend de archivos, su directorio temporal contendrá un número creciente de archivos.

Para comprender este problema, considere lo que sucede con el backend de la base de datos. Cuando un usuario inicia sesión, Django agrega una fila al django_session tabla de base de datos. Django actualiza esta fila cada vez que cambian los datos de la sesión. Si el usuario cierra la sesión manualmente, Django elimina la fila. Pero si el usuario lo hace no cerrar sesión, la fila nunca se elimina. Un proceso similar ocurre con el backend del archivo.

Django hace no proporcionar purga automática de sesiones caducadas. Por lo tanto, es su trabajo purgar las sesiones caducadas de forma regular. Django proporciona un comando de gestión de limpieza para este propósito: clearsessions. Se recomienda llamar a este comando de forma regular, por ejemplo, como un trabajo cron diario.

Tenga en cuenta que el backend de la caché no es vulnerable a este problema, porque las cachés eliminan automáticamente los datos obsoletos. Tampoco lo es el backend de las cookies, porque los navegadores de los usuarios almacenan los datos de la sesión.

Ajustes

Unos pocos Configuración de Django le da control sobre el comportamiento de la sesión:

  • 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

Seguridad de la sesión

Los subdominios dentro de un sitio pueden establecer cookies en el cliente para todo el dominio. Esto hace posible la fijación de la sesión si se permiten cookies de subdominios no controlados por usuarios de confianza.

Por ejemplo, un atacante podría iniciar sesión good.example.com y obtenga una sesión válida para su cuenta. Si el atacante tiene control sobre bad.example.com, pueden usarlo para enviarle su clave de sesión, ya que un subdominio puede configurar cookies en *.example.com. Cuando tu visitas good.example.com, iniciará sesión como el atacante y podría ingresar inadvertidamente sus datos personales confidenciales (por ejemplo, información de la tarjeta de crédito) en la cuenta del atacante.

Otro posible ataque sería si good.example.com establece su SESSION_COOKIE_DOMAIN para "example.com" lo que haría que las cookies de sesión de ese sitio se envíen a bad.example.com.

Detalles técnicos

  • El diccionario de sesión acepta cualquier json valor serializable cuando se usa JSONSerializer o cualquier objeto de Python seleccionable al usar PickleSerializer. Ver el pickle módulo para obtener más información.
  • Los datos de la sesión se almacenan en una tabla de base de datos denominada django_session .
  • Django solo envía una cookie si es necesario. Si no establece ningún dato de sesión, no enviará una cookie de sesión.

los SessionStore objeto

Cuando trabaja con sesiones internamente, Django usa un objeto de almacenamiento de sesión del motor de sesión correspondiente. Por convención, la clase de objeto del almacén de sesiones se denomina SessionStore y está ubicado en el módulo designado por SESSION_ENGINE.

Todos SessionStore las clases disponibles en Django heredan de SessionBase e implementar métodos de manipulación de datos, a saber:

  • exists()
  • create()
  • save()
  • delete()
  • load()
  • clear_expired()

Para construir un motor de sesión personalizado o personalizar uno existente, puede crear una nueva clase heredando de SessionBase o cualquier otro existente SessionStore clase.

Puede ampliar los motores de sesión, pero hacerlo con motores de sesión respaldados por bases de datos generalmente requiere un esfuerzo adicional (consulte la siguiente sección para obtener más detalles).

Ampliación de motores de sesión respaldados por bases de datos

Crear un motor de sesión personalizado respaldado por una base de datos basado en los incluidos en Django (a saber db y cached_db) se puede hacer heredando AbstractBaseSession y también SessionStore clase.

AbstractBaseSession y BaseSessionManager son importables de django.contrib.sessions.base_session para que se puedan importar sin incluir django.contrib.sessions en INSTALLED_APPS.

class base_session.AbstractBaseSession

El modelo de sesión base abstracto.

session_key

Clave primaria. El campo en sí puede contener hasta 40 caracteres. La implementación actual genera una cadena de 32 caracteres (una secuencia aleatoria de dígitos y letras ASCII minúsculas).

session_data

Una cadena que contiene un diccionario de sesión codificado y serializado.

expire_date

Una fecha y hora que indica cuándo expira la sesión.

Las sesiones caducadas no están disponibles para un usuario, sin embargo, aún pueden almacenarse en la base de datos hasta que clearsessions se ejecuta el comando de gestión.

classmethod get_session_store_class()

Devuelve una clase de tienda de sesión para usar con este modelo de sesión.

get_decoded()

Devuelve datos de sesión decodificados.

La decodificación la realiza la clase de almacenamiento de sesiones.

También puede personalizar el administrador de modelos subclasificando BaseSessionManager:

class base_session.BaseSessionManager
encode(session_dict)

Devuelve el diccionario de sesión dado serializado y codificado como una cadena.

La codificación la realiza la clase de almacenamiento de sesiones vinculada a una clase de modelo.

save(session_key, session_dict, expire_date)

Guarda los datos de la sesión para una clave de sesión proporcionada o elimina la sesión en caso de que los datos estén vacíos.

Personalización de SessionStore Las clases se logran invalidando los métodos y las propiedades descritas. debajo:

class backends.db.SessionStore

Implementa el almacenamiento de sesiones respaldado por la base de datos.

classmethod get_model_class()

Anule este método para devolver un modelo de sesión personalizado si lo necesita.

create_model_instance(data)

Devuelve una nueva instancia del objeto de modelo de sesión, que representa el estado de la sesión actual.

Reemplazar este método brinda la capacidad de modificar los datos del modelo de sesión antes de que se guarden en la base de datos.

class backends.cached_db.SessionStore

Implementa el almacenamiento de sesiones respaldado por la base de datos en caché.

cache_key_prefix

Un prefijo agregado a una clave de sesión para construir una cadena de clave de caché.

Ejemplo

El siguiente ejemplo muestra un motor de sesión personalizado respaldado por una base de datos que incluye una columna de base de datos adicional para almacenar un ID de cuenta (brindando así una opción para consultar la base de datos para todas las sesiones activas para una cuenta):

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

Si está migrando desde el sistema integrado de Django cached_db tienda de sesiones a una personalizada basada en cached_db, debe anular el prefijo de la clave de caché para evitar un conflicto de espacio de nombres:

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

    # ...

ID de sesión en URL

El marco de sesiones de Django se basa total y exclusivamente en cookies. No recurre a poner ID de sesión en URL como último recurso, como hace PHP. Esta es una decisión de diseño intencional. Ese comportamiento no solo hace que las URL sean feas, sino que también hace que su sitio sea vulnerable al robo de ID de sesión a través del encabezado “Referer”.