Le Touilleur Express

  • Accueil
  • A propos de l’auteur
  • A propos du Touilleur Express
Next Previous

Your session should never expire

1 janvier, 2013
© volff - Fotolia.com

© volff – Fotolia.com

Disclaimer : cet article date de fin 2011… Je viens de le sortir de la cave comme une bonne bouteille. Les lecteurs fidèles y retrouveront mes poncifs et cela fera un peu répétitif. Mais bon, comme un bon vin, il fallait le laisser vieillir.

La scène se passe il y a quelques mois. Il est 2h10 du matin.

Cela fait plusieurs heures que je clique et que je travaille dans ce logiciel Web pour un client, un truc de CRM/Wiki/Machin en java. C’est une application Web, écrite avec un framework Java, peu importe le nom. Il y a des formulaires à remplir. Je remarque que le développeur qui a fait cela s’est lâché sur l’utilisation de l’ajax. Il y a des listes déroulantes qui se remplissent via une requête Ajax.

J’imagine que le développeur a passé un certain temps à « ajaxiser » ces 3 pauvres listes déroulantes. La première permet de choisir son pays. Quel génie ce mec : il a ajaxisé la liste des pays, dès fois que l’Argentine disparaisse et qu’un autre pays soit ajouté, au moins on est tranquille. Il doit recharger du serveur cette liste de pays. Super mon champion.

Comme c’est de l’ajax, je me dis que je peux commencer à faire autre chose pendant que la PREMIERE liste essaye de dire que j’habite en FRANCE au serveur. Je tente la sélection de mon genre (Homme/Femme) toujours ajaxisé pour envoyer la sélection au serveur…. Baam cela plante la page… Je rigole. C’est de l’Ajax mais codé par un paysan.

Bon disons qu’ensuite j’arrive à remplir ce formulaire et à l’envoyer au serveur… toujours en Ajax… sans m’empêcher cependant de cliquer plusieurs fois…

Je regarde ce petit GIF animé qui tourne en haut à droite qui me signale qu’il faut attendre et ne surtout pas toucher à autre chose, même si tout est fait en Ajax. J’imagine différentes tortures et supplices pour celui qui a codé cela. J’essaye de deviner le nom du framework en regardant l’URL, mais comme souvent en Java, elle ne ressemble à rien.

Ah c’est bon, la deuxième liste déroulante s’est remplie. Je sélectionne le département. Et là une troisième liste repart vers le serveur, GIF animé pour dire « TOUCHE PAS C’EST DE L’ASYNCHRONE »… J’imagine la bouteille d’Ajax avec une paille dans le nez du développeur…

Il est 2h25, je suis fatigué….

Le GIF animé tourne, tourne, tourne…

Je m’endors.

Il est 3h du matin, j’ai piqué du nez. Ma fenêtre de navigateur n’a pas bougé. Je reprends la souris pour terminer mon boulot. Je clique sur un bouton et là… et là mon ami : une page d’erreur. Un petit texte rouge bien présenté, entouré d’un cadre rouge foncé, s’affiche sur la page. A croire que le développeur Web a mis tout son budget dans le CSS « error-box » avec la même énergie que ses exploits avec Ajax…

« Your session has expired« 

Mais c’est quoi ce message ?

Je pensais que nous, développeurs Architectes Java, inventeurs de l’Inversion de Contrôle pour les masses, maître Jedi de la séparation des couches, super-kungfu master du mapping objet-relationnel, oui nous LES ARCHITECTES, je pensais que l’on avait compris qu’une application Web devait gérer la session.

Genre y’a que lorsque tu fais du Java que tu as ce genre de soucis. Va faire 5mn de Rails ou de Django et on en reparle.

Ah pardon… c’est vrai que c’est pas entreprise ou « un projet de la vraie vie ».

Bref un GIF animé et une session qui a expirée. J’imagine que le développeur a séparé en plusieurs couches son code, en mettant une tartine de JPA, une abstraction avec des entités, une tartine de service, un fine tranche de sécurité et un gros paquet de framework web pour empaqueter le tout… Oui mon gars, les couches c’est bien, mais il faut aussi un peu comprendre ce que l’on fait non ?

Le protocole HTTP est simple. 5 verbes de commandes. Il faut au moins comprendre GET et POST. Essayons de se dire que GET est destiné au chargement d’une donnée, et que POST est destiné à modifier une information sur le serveur. Un principe de base : une succession d’appel via GET est dit « idempotent » alors qu’une suite d’appels via POST ne l’est pas. De là, comprendre la notion de ressources, d’URI, d’adressage, bref du web quoi.

Gregor Hohpe, l’auteur du livre Enterprise Integration Pattern, l’explique simplement sur son blog :

“In the world of distributed systems, idempotency translates to the fact that an operation can be invoked repeatedly without changing the result.”

Ensuite, le protocole HTTP est stateless.

The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. It is a generic, stateless, protocol which can be used for many tasks beyond its use for hypertext, such as name servers and distributed object management systems, through extension of its request methods, error codes and headers [47]. A feature of HTTP is the typing and negotiation of data representation, allowing systems to be built independently of the data being transferred. (source)

La notion de session n’existe que grâce aux Cookies, à la ré-écriture d’URL ou lorsque vous postez des données dans des champs cachés. Tout le reste, ce n’est pas du Web. Lorsque vous avez un cookie technique JSESSION_ID qui se balade avec vous, et que l’état de ce que vous êtes entrain de faire dans l’application est stocké en mémoire, vous utilisez une application avec un état conversationnel du côté serveur. Je ne dis pas que c’est bien ou pas bien. Je dis que cela entraîne des problèmes qui n’existent pas lorsque vous faîtes vraiment du Web.

Lorsque nous utilisons des cookies signés pour stocker des identifiants de session, on imagine qu’il faut ensuite recharger de la base de données toutes les informations… C’est possible et cela fonctionne correctement, mais la base de données n’est pas faite pour cela. En règle génèrale on utilise alors un cache partagé avec ehcache, memcached ou Redis. C’est bien plus efficace que de laisser faire le framework Web à votre place.

Lorsque j’ai vu le message « Your F**ing sesson has expired », je me suis vraiment interrogé sur la motivation du développeur du framework qui a pondu cela. En quoi n’est-t-il pas capable de stocker un état et de le recharger lorsque je relance ma requête ?

En observant les URLs, nous avons le début d’une réponse (j’ai changé le nom du framework pour respecter son anonymat) :

http://www.monserveur.fr/?crocket:interface=:6:1:::

Qu’est-ce que c’est que cette URI ? Mais c’est de la merde comme dirait Jean-Pierre. Ce n’est pas du Web, c’est un produit industriel bourré de polyphospates que l’on pense utiliser pour faire des économies, mais qui ne vaut rien !

Bref dans un grand délire mégalowebmaniac j’ai lancé une phrase à 2 balles dont je ne mesure pas la portée mais que j’ai envie de proposer à toi, cher lecteur. Cette phrase, la voici :

Votre session n’a pas à expirer pour un problème technique.

Une session devrait expirer pour une raison métier mais pas pour des raisons techniques. Elle ne devrait pas expirer parce qu’un créateur de framework pense que c’est le seul moyen de libérer des ressources.

En poussant un peu, nous pourrions dire que  le message « technique » signifiant que votre session a expiré ne devrait pas exister.

Du tout.

Lorsque vous rechargez la fenêtre de votre navigateur, et que l’état, la session ou la conversation est perdue, vous n’êtes pas entrain d’utiliser une application Web. La bonne nouvelle c’est qu’une grande majorité des frameworks Webs Java gèrent cela sans trop de soucis. La mauvaise nouvelle c’est que ce n’est pas l’approche recommandée ou documentée dans les tutoriaux.

Qu’est-ce qu’une application Web ?
Il s’agit d’une application hébergée sur un ou plusieurs serveurs, utilisée via un navigateur ou une API REST.

C’est une application qui passe ce test :

– fonctionne avec plusieurs onglets de navigateur
– propose des URI facilement bookmarkable, voire même qu’un utilisateur peut retenir
– utilise correctement GET et POST
– fonctionne de manière transparente avec un ou plusieurs serveurs sans problèmes de session
– n’utilise pas de GIF animé pour faire attendre l’utilisateur
– ne plante pas comme une merde lorsque l’utilisateur clique sur le bouton « Back » ou retour.
– ne plante pas lorsque je clique comme un bourin sur « Reload » une centaine de fois pour me défouler, surtout lorsque je vois « crocket » dans l’url du navigateur
– ne génère pas des pages webs de 700ko avec 3 pauvres tableaux ajaxisés.

La majorité des frameworks Webs permettent de suivre et de respecter ces principes.

Alors où stocker ces données de conversation ?

© kritiya - Fotolia.com

© kritiya – Fotolia.com

Il y a différentes solutions utilisées aujourd’hui dans le développement d’applications :

  • mettre plus de mémoire et prétendre que ce problème n’arrive pas « sur les vrais projets de la vraie vie »
  • stocker les id des objets primaires dans un cookie signé et recharger les entités de la base à chaque appel
  • utiliser un cache partagé comme memcached, ehcache ou redis, stocker un jeton dans un cookie signé et charger les id des objets primaires dans un cache
  • passer par la ré-écriture d’URL simple
L’idée d’utiliser des cookies et de recharger la base peut sembler bizarre, d’autant plus lorsque l’on ne maîtrise pas trop le fonctionnement d’une base simple type SGBDR. En fait cela correspond à faire soit-même ce qui est effectué en général par un framework Web Java complet. Avant d’aller plus loin, voyons comment fonctionne une bonne partie des frameworks webs Java aujourd’hui. Lorsque vous naviguez de page en page avec une application classique en Java, vous verrez souvent un cookie de type JSESSIONID se balader avec vous. Voyez cela comme un ticket au pressing, qui permet au serveur de recharger votre session d’une page à l’autre. C’est cela que je n’aime pas, que j’appelle un « état conversationnel » et qui fait que ce type de solution est vouée à disparaître. Lorsque la mémoire vient à manquer, le serveur d’application sérialise votre session sur le disque afin de libérer des ressources, pour pouvoir prendre d’autres clients. Puis au bout d’un certain temps, il efface complètement votre session, l’histoire de la petite croix rouge du début de cet article. Bref le symptôme qui te prouve par A+B que finalement, on était pas capable de restaurer ta session, ou même que si nous l’avions restaurée, de toutes les façons elle est peut-être obsolète… alors on l’efface.
L’approche que j’utilise est différente, car je peux contrôler finement ce que je stocke.
Aujourd’hui en 2012 je préfère un outil qui ne me cache pas la nécessité de gérer une session. Je pense qu’un framework qui essaye de trouver une réponse technique à un problème fonctionnel n’est pas bon. Une réponse technique c’est un délai pré-configuré après lequel le framework détruit une session (ou la sérialise sur le disque). Un problème fonctionnel c’est le temps maximum que nous laissons à un client pour passer un achat, utiliser une application de gestion ou effectuer des opérations bancaires.

Imaginez un seul instant ce principe : votre session « technique » ne doit pas expirer, jamais. Si quelque chose expire, cela doit être lié au métier. Mais pas à un problème technique ou à une décision prise par le framework.

Bref, j’ai terminé à 03h10.

 

0 no like

Articles similaires:

Pas d'articles similaires

  • Sebastien Lorber 1 janvier 2013 at 17 h 24 min

    Sinon on peut aussi mettre des input type hidden un peu partout dans l’appli 😀

  • Piwaï 4 janvier 2013 at 12 h 33 min

    « http://www.monserveur.fr/?crocket:interface=:6:1::: » => Les « : » me font penser à du Wicket.. Rien de sûr, mais ce #&!@ de site du CFP Devoxx est en Wicket, et ya des f*cking « : » partout dans l’URL…

  • Alexis 4 janvier 2013 at 16 h 39 min

    @Piwaï en même temps crocket ça me fait penser également à… de la nourriture pour chat ou chien 😉

  • Francois 9 janvier 2013 at 17 h 23 min

    Dans le framework Wicket, pour avoir des urls correspondants à vos specifs, il suffit d’employer le MountedMapper correspondant.
    Wicket est un framework statefull, d’où l’usage de la session.

    Concernant la Session, celel-ci n’est pas propre à un framework ni à un language.

    http://en.wikipedia.org/wiki/Session_(computer_science)

    Bon dev
    François

  • Adrien 14 janvier 2013 at 21 h 15 min

    @Francois,
    +1000
    des petits rappels ne font pas de mal de temps en temps.

    Adrien

  • doanduyhai 23 janvier 2013 at 13 h 04 min

    Il y a aussi un autre problème de design à la base.

    En quoi la liste des pays devrait elle dépendre de l’utilisateur connecté ?

    Plus généralement la liste des pays devrait être une ressource REST générique accessible par tous les users. Il n’y a donc pas besoin d’avoir une session active pour la récupérer…

    Evidemment se pose le problème de sécuriser l’API Rest pour éviter les attaques DDOS mais c’est un autre sujet…

Derniers articles

  • L’instant T où tu poses ta dém…

    Retour d’expérience sur la démission et le moment où vous devez quitter une entreprise.

    6 likes

    24 octobre, 2024
  • The « Robinson » projection – comprendre son système d’information

    Nous sommes en juillet 2022 chez Doctolib. Je travaille sur un projet

    5 likes

    22 octobre, 2024
  • Réussir son démarrage comme Staff/Principal Engineer dans une nouvelle entreprise

    Je prépare une présentation avec mon collègue Théotime pour la conférence Cloud

    3 likes

    6 octobre, 2024

Mots clés

Apple (32) Architecture (14) Big Data (5) Conference (8) Devoxx (55) Dev Web (37) Doctolib (2) geekevent (1) groovy (2) Innoteria (11) Java (517) Linux (10) Non classé (15) Perso (266) Recrutement (2) Scala (30) scrum (43) Société (3) Staff Engineer (5) Startup (21) Web 2.0 (67)

Le Touilleur Express

Blog par Nicolas Martignole

Contactez-moi : nicolas@touilleur-express.fr

Suivez-moi sur X (Twitter) : @nmartignole

Copyright© 2008 - 2024 Nicolas Martignole | Tous droits réservés
  • A propos de l’auteur
  • A propos du Touilleur Express
  • Reset Password

Le Touilleur Express