Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Black Friday: -25€ dès 75€ sur les livres en ligne, vidéos... avec le code BWEEK25. J'en profite !
  1. Livres et vidéos
  2. Django
  3. Le middleware Django
Extrait - Django Industrialisez vos développements Python
Extraits du livre
Django Industrialisez vos développements Python Revenir à la page d'achat du livre

Le middleware Django

Présentation

Le middleware Django n’a pas grand-chose à voir avec ce que l’on entend classiquement par middleware en informatique. Le middleware Django est un mécanisme, permettant d’intercepter les requêtes et les réponses HTTP, à chaque étape de leur traitement. C’est un système simple et léger de « plug-ins », plug-ins par lesquels les requêtes et les réponses vont transiter, pour être éventuellement altérées. Chaque plug-in du middleware appelé plus simplement middleware est une classe Python implémentant des méthodes spécifiques, ces méthodes étant appelées à diverses étapes du processus de traitement de la requête et de l’élaboration de la réponse.

Chaque middleware réalise une tâche spécifique. Par exemple le middleware SessionMiddleware, gère la session utilisateur sans que l’on ait à s’en soucier dans l’écriture des vues.

Les middlewares peuvent dépendre les uns des autres, et en cela l’ordre dans lequel ils sont exécutés est important.

Nous allons voir comment cela fonctionne, comment activer ou désactiver un middleware, et comment écrire un middleware spécifique à votre projet.

Installer et activer un middleware

Pour activer un code middleware particulier, il faut l’ajouter au n-uplet de la variable MIDDLEWARE_CLASSES du fichier de configuration settings.py. Cette variable attend une suite de chaînes de caractères, chaque chaîne représentant une classe middleware identifiée par son chemin (PATH) Python complet.

Prenons la configuration initiale des middlewares telle que la configure la commande django-admin.py startproject :


MIDDLEWARE_CLASSES = ( 
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    # Uncomment the next line for simple clickjacking protection: 
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 
)
 

Pour désactiver un middleware, il suffit de ne pas le mettre dans la liste.

Principes de fonctionnement

On peut utiliser Django sans avoir installé aucun middleware, bien qu’il soit fortement suggéré d’utiliser au moins le middleware CommonMiddleware.

Comme certains middlewares peuvent dépendre les uns des autres, l’ordre dans lequel ils sont positionnés dans MIDDLEWARE_CLASSES est important, car il va conditionner l’ordre dans lequel les middlewares vont être exécutés.

Par exemple, le middleware d’authentification des utilisateurs AuthenticationMiddleware s’appuie sur une gestion des sessions, il a donc besoin que les sessions existent et soient gérées avant d’être exécuté. Il ne peut donc travailler qu’une fois le travail du middleware SessionMiddleware effectué, c’est pourquoi il est positionné après le middleware SessionMiddleware dans la liste.

Le principe d’être exécuté ″avant″ est valable pour le traitement des requêtes. Lorsque l’on traitera les réponses aux requêtes, l’ordre sera inversé, les premiers seront les derniers et réciproquement. À l’aller on empile, au retour on dépile ; voir le schéma explicatif.

1. Ordre précis d’exécution des méthodes des middlewares

Un middleware est une classe Python, ordinaire, sans méthode __init__(). Cette classe Python doit implémenter les cinq méthodes ci-dessous. L’ordre des méthodes dans la classe n’a pas d’importance, mais nous les avons positionnées dans l’ordre dans lequel Django les appellera à l’exécution ; nous vous conseillons donc d’en faire de même.

Exemple :


class MonMiddleware:  
    def process_request(self, request):  
       return None  
  
    def process_view(self, request, view_func, view_args, view_kwargs): 
        return None  
  
    def process_template_response(self, request, response):  
        return response  
  
    def process_response(self, request, response):  
        return response  
  
    def process_exception(self, request, exception):  ...

Liste et description des middlewares fournis avec Django

Cache middleware

class UpdateCacheMiddleware

class FetchFromCacheMiddleware

Gèrent le cache de Django.

Common middleware

class CommonMiddleware

  • Gère les traitements courants (communs) du développement web.

    Interdit l’accès aux user-agents configurés sous la forme d’expressions régulières dans la variable DISALLOWED_USER_AGENTS du fichier setting.py.

  • Réalise de la réécriture d’URL en fonction de APPEND_SLASH et PREPEND_WWW.

    Si APPEND_SLASH est à True et que l’URL initiale ne se termine pas par un slash (’/’) alors, si Django ne la trouve pas dans la configuration des URL, il essaiera d’utiliser la même URL mais terminée par slash.

    Si PREPEND_WWW est à True, les URL qui ne commencent pas par ”www.” seront redirigées vers la même URL en y ajoutant "www.".

  • Gère les ETag en fonction de la variable USE_ETAGS.

    Si USE_ETAGS est à True, Django calculera un « ETag » pour chaque réponse en calculant un digest MD5 du contenu de la réponse pour chaque réponse.

Un ETag est une clef de hachage utilisée aussi bien pour le cache que pour dire si une page a changé.

class BrokenLinkEmailsMiddleware

Ce middleware envoie des notifications par mail aux gestionnaires du site en cas de liens rompus.

GZip...

Ordre d’installation des middlewares Django

Le middleware UpdateCacheMiddleware doit être positionné avant les middlewares qui indiquent si les headers sont variables (Vary header), c’est-à-dire : SessionMiddleware, GZipMiddleware et LocaleMiddleware.

Le middleware GZipMiddleware doit être positionné avant les middlewares qui sont susceptibles de modifier le contenu de la réponse et après UpdateCacheMiddleware qui modifie les headers.

Le middleware GZipMiddleware doit être positionné avant CommonMiddleware.

Le middleware SessionMiddleware doit être positionné après UpdateCacheMiddleware, car il modifie les headers.

Le middleware LocaleMiddleware doit être positionné le plus tôt possible, après le middleware SessionMiddleware et CacheMiddleware.

Le middleware CommonMiddleware doit être positionné avant les middlewares modifiant la réponse et après GZipMiddleware pour que le Etag ne soit pas calculé sur la base du contenu zippé.

Le middleware CsrfViewMiddleware doit être positionné avant tous les middlewares qui font l’hypothèse que ces attaques sont déjà traitées.

Le middleware AuthenticationMiddleware doit être positionné après SessionMiddleware, car il utilise les sessions.

Le middleware MessageMiddleware doit être positionné après...