HTTP (HyperText Transfer Protocol) a été conçu pour prendre en charge un modèle de requête-réponse sans état pour le transfert de données d'un serveur vers un client. Sa première version, 1.0, prenait en charge un rapport requête/connexion purement de 1:1 (c'est-à-dire qu'une paire requête-réponse était prise en charge par connexion).
La version 1.1 a étendu ce ratio à N:1, c'est-à-dire au nombre de requêtes par connexion. Cela a été fait pour répondre à la complexité croissante des pages Web, y compris les nombreux objets et éléments qui doivent être transférés du serveur au client.
Avec l’adoption de la version 2.0, HTTP a continué à prendre en charge un modèle à plusieurs requêtes par connexion. Ses changements les plus radicaux concernent l’échange d’en-têtes et le passage d’un transfert textuel à un transfert binaire.
Quelque part en cours de route, HTTP est devenu plus qu’un simple mécanisme de transfert de texte et d’images d’un serveur à un client ; il est devenu une plate-forme pour les applications. L’omniprésence du navigateur, la nature multiplateforme et la facilité avec laquelle les applications pouvaient être déployées sans le coût élevé de la prise en charge de plusieurs systèmes d’exploitation et environnements étaient certainement attrayantes. Malheureusement, HTTP n’a pas été conçu pour être un protocole de transport d’application. Il a été conçu pour transférer des documents. Même les utilisations modernes de HTTP telles que celles des API supposent une charge utile de type document. Un bon exemple est JSON, un format de données de paire clé-valeur transféré sous forme de texte. Bien que les documents et les protocoles d’application soient généralement basés sur du texte, la ressemblance s’arrête là.
Les applications traditionnelles nécessitent un moyen de maintenir leur état, alors que les documents n'en ont pas besoin. Les applications sont construites sur des flux et des processus logiques, qui nécessitent tous deux que l'application sache où se trouve l'utilisateur à ce moment-là, ce qui nécessite un état. Malgré la nature intrinsèquement sans état du protocole HTTP, il est devenu le protocole de transport d’application de facto du Web. Dans ce qui est certainement l’un des hacks les plus largement acceptés et les plus utiles de l’histoire technique, HTTP a reçu les moyens par lesquels l’état pouvait être suivi tout au long de l’utilisation d’une application. C'est dans ce « hack » que les sessions et les cookies entrent en jeu.
Les sessions sont la manière dont les serveurs Web et d'applications maintiennent leur état. Ces simples blocs de mémoire sont associés à chaque connexion TCP établie avec un serveur Web ou d'application et servent de stockage en mémoire pour les informations dans les applications basées sur HTTP.
Lorsqu'un utilisateur se connecte à un serveur pour la première fois, une session est créée et associée à cette connexion. Les développeurs utilisent ensuite cette session comme un lieu pour stocker des éléments de données pertinents pour l'application. Ces données peuvent aller d'informations importantes telles qu'un identifiant client à des données moins importantes telles que la façon dont vous souhaitez voir la première page du site affichée.
Le meilleur exemple d’utilité d’une session est celui des paniers d’achat, car nous avons presque tous fait des achats en ligne à un moment ou à un autre. Les articles d'un panier restent pendant toute la durée d'une « session » car chaque article de votre panier est représenté d'une manière ou d'une autre dans la session sur le serveur. Un autre bon exemple est celui des applications de configuration ou de personnalisation de produits de type assistant. Ces « mini » applications vous permettent de parcourir un ensemble d’options et de les sélectionner ; à la fin, vous êtes généralement choqué par le coût estimé de toutes les fioritures que vous avez ajoutées. Au fur et à mesure que vous cliquez sur chaque « écran d’options », les autres options que vous avez choisies sont stockées dans la session afin qu’elles puissent être facilement récupérées, ajoutées ou supprimées.
Les applications modernes sont conçues pour être sans état, mais leurs architectures peuvent ne pas être conformes à ce principe. Les méthodes modernes de mise à l’échelle s’appuient souvent sur des modèles architecturaux tels que le sharding, qui nécessite de routage des requêtes en fonction de certaines données indexables, comme le nom d’utilisateur ou le numéro de compte. Cela nécessite une sorte d’approche avec état, dans laquelle les données indexables sont transportées avec chaque demande pour garantir un routage et un comportement d’application appropriés. À cet égard, les applications et API « sans état » modernes nécessitent souvent des soins et une alimentation similaires à ceux de leurs prédécesseurs avec état.
Le problème est que les sessions sont liées aux connexions, et que les connexions restent inactives pendant trop longtemps. De plus, la définition de « trop long » pour les connexions est assez différente de celle appliquée aux sessions. La configuration par défaut de certains serveurs Web, par exemple, consiste à fermer une connexion une fois qu'elle est inactive (c'est-à-dire qu'aucune autre demande n'a été effectuée) pendant 15 secondes. À l’inverse, une session sur ces serveurs Web restera par défaut en mémoire pendant 300 secondes, soit 5 minutes. De toute évidence, les deux sont en désaccord l'un avec l'autre, car une fois la connexion expirée, à quoi sert la session si elle est associée à la connexion ?
Vous pourriez penser que vous pourriez simplement augmenter la valeur du délai d’expiration de la connexion pour correspondre à la session et résoudre cette disparité. Augmenter le délai d'attente signifie que vous allez potentiellement dépenser de la mémoire pour maintenir une connexion qui peut ou non être utilisée. Cela peut diminuer la capacité totale des utilisateurs simultanés de votre serveur et, à terme, entraver ses performances. Et vous ne voulez certainement pas réduire le délai d'expiration de la session pour qu'il corresponde au délai d'expiration de la connexion, car la plupart des gens prennent plus de cinq minutes pour magasiner ou personnaliser leur nouveau jouet.
Remarque importante : Bien que HTTP/2 résolve certains de ces problèmes, il en introduit d’autres liés au maintien de l’état. Bien que cela ne soit pas requis par la spécification, les principaux navigateurs n'autorisent que HTTP/2 sur TLS/SSL. Les deux protocoles nécessitent de la persistance pour éviter le coût de performance de la renégociation, ce qui nécessite à son tour une connaissance de session, également appelée comportement avec état.
Ainsi, vous vous retrouvez avec des sessions qui restent en mémoire sur le serveur même après que leurs connexions associées ont été interrompues en raison d'une inactivité, ce qui consomme des ressources précieuses et peut potentiellement mettre en colère les utilisateurs pour lesquels votre application ne fonctionne tout simplement pas.
Heureusement, ce problème est résolu grâce à l’utilisation de cookies.
Les cookies sont des éléments de données stockés sur le client par le navigateur. Les cookies peuvent stocker, et stockent, toutes sortes d’informations intéressantes sur vous, vos applications et les sites que vous visitez. Le terme « cookie » est dérivé de « cookie magique », un concept bien connu de l'informatique UNIX qui a inspiré à la fois l'idée et le nom. Les cookies sont créés et partagés entre le navigateur et le serveur via l'en-tête HTTP, Cookie.
Biscuit: JSESSIONID=9597856473431 Cache-Control : no-cache Hôte : 127.0.0.2:8080 Connexion : Garder en vie
Le navigateur sait automatiquement qu'il doit stocker le cookie dans l'en-tête HTTP d'un fichier sur votre ordinateur, et il garde une trace des cookies pour chaque domaine. Les cookies pour un domaine donné sont toujours transmis au serveur par le navigateur dans les en-têtes HTTP, de sorte que les développeurs d'applications Web peuvent récupérer ces valeurs simplement en les demandant côté serveur de l'application.
Le problème de durée de session/connexion est résolu grâce à un cookie. Presque toutes les applications Web modernes génèrent un « ID de session » et le transmettent sous forme de cookie. Cela permet à l'application de trouver la session sur le serveur même après la fermeture de la connexion à partir de laquelle la session a été créée. Grâce à cet échange d’identifiants de session, l’état est maintenu même pour un protocole sans état comme HTTP. Mais que se passe-t-il lorsque l’utilisation d’une application Web dépasse les capacités d’un seul serveur Web ou d’applications ? Habituellement, un équilibreur de charge ou, dans les architectures actuelles, un contrôleur de distribution d'applications (ADC), est introduit pour faire évoluer l'application de sorte que tous les utilisateurs soient satisfaits de la disponibilité et des performances.
Dans les applications modernes, les cookies peuvent toujours être utilisés, mais d’autres en-têtes HTTP deviennent critiques. Les clés API pour l’authentification et l’autorisation sont souvent transportées via un en-tête HTTP, ainsi que d’autres en-têtes personnalisés qui transportent les données nécessaires au routage et à la mise à l’échelle appropriée des services back-end. La question de savoir si l’utilisation du « cookie » traditionnel pour transporter ces données ou d’un autre en-tête HTTP est moins importante que la reconnaissance de son importance pour l’architecture globale.
Le problème avec cela est que les algorithmes d’équilibrage de charge ne s’intéressent généralement qu’à la distribution des requêtes entre les serveurs. Les techniques d'équilibrage de charge sont basées sur des algorithmes standard du secteur tels que le round robin, le moins de connexions ou le temps de réponse le plus rapide. Aucun d'entre eux n'est avec état, et il est possible pour un même utilisateur que chaque demande adressée à une application soit distribuée à un serveur différent. Cela rend tout le travail effectué pour implémenter l'état pour HTTP inutile, car les données stockées dans la session d'un serveur sont rarement partagées avec d'autres serveurs du « pool ».
C’est là que le concept de persistance entre en jeu.
La persistance, également connue sous le nom de stickiness, est une technique mise en œuvre par les ADC pour garantir que les requêtes d'un seul utilisateur sont toujours distribuées au serveur sur lequel elles ont démarré. Certains produits et services d’équilibrage de charge décrivent cette technique comme des « sessions persistantes », ce qui est un terme tout à fait approprié.
La persistance est utilisée depuis longtemps pour équilibrer la charge des sites compatibles SSL/TLS, car une fois le processus de négociation (qui nécessite beaucoup de calculs) terminé et les clés échangées, le redémarrage du processus dégraderait considérablement les performances. Ainsi, les ADC ont mis en œuvre la persistance des sessions SSL pour garantir que les utilisateurs étaient toujours dirigés vers le même serveur auquel ils s'étaient connectés en premier.
Au fil des années, les implémentations de navigateurs ont nécessité le développement d’une technique pour éviter une renégociation coûteuse de ces sessions. Cette technique est appelée persistance basée sur les cookies.
Plutôt que de s'appuyer sur l'ID de session SSL/TLS, l'équilibreur de charge insérerait un cookie pour identifier de manière unique la session la première fois qu'un client accède au site, puis ferait référence à ce cookie dans les demandes ultérieures pour conserver la connexion au serveur approprié.
Le concept de persistance basé sur les cookies a depuis été appliqué aux sessions d’application, en utilisant les informations d’ID de session générées par les serveurs Web et d’applications pour garantir que les demandes des utilisateurs sont toujours dirigées vers le même serveur au cours de la même session. Sans cette capacité, les applications nécessitant un équilibrage de charge devraient trouver un autre moyen de partager les informations de session ou recourir à des délais d'expiration de session et de connexion de plus en plus longs au point que le nombre de serveurs nécessaires pour prendre en charge leur base d'utilisateurs deviendrait rapidement ingérable.
Bien que la forme de persistance la plus courante soit implémentée à l’aide d’ID de session transmis dans l’en-tête HTTP, les ADC peuvent aujourd’hui également persister sur d’autres éléments de données. Toutes les données pouvant être stockées dans un cookie ou dérivées des en-têtes IP, TCP ou HTTP peuvent être utilisées pour conserver une session. En fait, toutes les données contenues dans un message d’application qui identifient de manière unique l’utilisateur peuvent être utilisées par un ADC intelligent pour maintenir une connexion entre le navigateur et un serveur.
HTTP est peut-être un protocole sans état, mais nous avons réussi à insérer de force l'état dans le protocole omniprésent. En utilisant la persistance et les contrôleurs de distribution d'applications, il est possible de concevoir des applications Web hautement disponibles et performantes sans rompre l'intégration quelque peu fragile des cookies et des sessions nécessaires au maintien de l'état.
Ces fonctionnalités sont ce qui donne l’état HTTP, bien que son implémentation et son exécution restent sans état. Sans cookies, sessions et persistance, nous aurions sûrement trouvé un protocole avec état sur lequel construire nos applications. Au lieu de cela, les fonctionnalités et les fonctions trouvées dans les contrôleurs de distribution d'applications servent d'intermédiaires entre les navigateurs (clients) et les serveurs pour fournir cette fonctionnalité, étendant l'utilité de HTTP au-delà des pages Web statiques et des applications traditionnelles aux architectures modernes basées sur les microservices et au chouchou de l'économie numérique, l'API.
Les dernières nouveautés en matière de renseignement sur les menaces applicatives.
La communauté F5 pour les forums de discussion et les articles d'experts.