mercredi 7 juillet 2010

Notifier une expiration de session utilisateur en Ajax

La problématique :

Dans la plupart des applications Intranet ou Extranet, le serveur gère un délai d’inactivité pour les sessions utilisateurs. Concrètement, cela veut dire que s’il se passe un certain délai (deux heures, par exemple) pendant lequel le serveur ne reçoit aucune requête HTTP de la part du client, le serveur prend l’initiative de détruire immédiatement et définitivement la session utilisateur. Cela veut dire qu’à partir de ce moment là, les données de l’utilisateur qui étaient préalablement stockées en session ont disparu. Ce mécanisme est important pour différentes raisons :
  • Il permet de libérer de la mémoire devenue inutilisée sur le serveur
  • C’est un élément des mécaniques de sécurité, indispensables dans les applications comme le webmail ou l’accès à des comptes bancaires.

Du point de vue de l’utilisateur, l’approche n’est pas la même. En fin de matinée, Jean-Paul se connecte à notre application pour traiter un document. Puis quelques minutes plus tard, il verrouille sont poste de travail et part déjeuner avec ses collègues. A son retour, café brûlant en main, il consulte ses mails, passe un coup de téléphone, puis reprend le traitement de son document. Il saisit ses données, clique sur le bouton de validation, confirme, et là… c’est le drame ! Sa session a expiré. Il doit se reconnecter, mais surtout, il doit recommencer le traitement de son document.
Alors comment faire pour satisfaire Jean-Paul sans désactiver les sécurités présentes sur le serveur d’application ?

Une solution simple et efficace :

Voici une solution extrêmement simple et facile à mettre en œuvre :
  1. Au chargement de la page HTML, déclencher un compte à rebours en Javascript sur le client.
  2. Lorsque le compte à rebours se termine, faire un appel Ajax pour vérifier si la session est effectivement terminée.
  3. Si la session a expiré, prendre l’action adéquate (i.e. rediriger l’utilisateur vers la page de connexion).

Le compte à rebours sur le client sera initialisé avec la durée du Timeout de session sur le serveur augmentée de quelques secondes par mesure de sécurité.

Mise en œuvre avec jQuery dans un environnement JSP :

Voici un exemple d’implémentation en jQuery et JSP. Ci-dessous, le code à intégrer dans les pages HTML.




A l’expiration du compte à rebours, un appel Ajax est déclenché vers la page checksession.jsp. Dans l’exemple donné ici, l’utilisateur est redirigé vers l’URL renvoyée par checksession.jsp. Voici le code de cette page :




L’idée est de tester la valeur d’un attribut de session connu que l’on sait non vide. S’il est vide, c’est que la session a expiré, et on renvoie dans la réponse HTTP la ressource vers laquelle rediriger l’utilisateur. Simple et efficace…

Améliorer le look and feel d’une application web

La deuxième moitié des années 2000 a été le théâtre de bouleversements majeurs dans nos navigateurs : démocratisation de l’Ajax, Web 2.0, réseaux sociaux ou collaboratifs, wikis… Aujourd’hui, il est fréquent que les applications web que nous utilisons dans notre vie privée – GMail, Yahoo!, Facebook, Picassa, Flickr, blogs – soient plus ergonomiques que celles que nous utilisons dans notre vie professionnelle. Si les utilisateurs finaux doivent s’en accommoder (ont-ils vraiment le choix ?), cette situation n’est pas satisfaisante lorsque l’on est éditeur de logiciels ou responsable applicatif au sein d’une grande organisation. Alors que faire ?

La méthodologie :
Pour un tel projet, qui ne comprendra finalement principalement que des modifications de style et d'ergonomie, inutile d'annoncer le lancement d'une v3 de l'application! Un cycle en V semble également peu adapté, pour de nombreuses raisons :
  • les phases amont au développement (architecture, spécifications, conception détaillée) sont souvent produites sous forme de documentation qui seront difficiles à valider par une MOA ou un département marketing,
  • certaines phases en aval du développement comme les tests unitaires seront difficiles à réaliser dans ce contexte,
  • risque d’effet-tunnel avec des délais difficiles à maîtriser
  • risque de surprise des clients (département marketing, MOA, utilisateurs finaux) en cas d’écart entre ce qui a été produit et ce qui est attendu.

Pour ce genre de démarche, il faut oublier la lourdeur du cycle en V et préférer une méthode permettant de faire des livraisons fréquentes, comme une méthode itérative ou une méthode agile de type SCRUM. Les livraisons sont facilitées par l’architecture même des applications web qui nécessitent seulement un déploiement sur un serveur et permettent :
  • A l’équipe de développement de montrer que le travail avance régulièrement
  • Aux clients de s’approprier le nouveau look de l’application sans être déroutés
  • Aux clients de faire des retours et de soumettre leurs idées pertinentes
Une livraison toutes les 4 à 6 semaines (en fonction de la durée du projet) semble un bon rythme. Il est intéressant, si c’est possible, de formaliser les livraisons en présentant les nouveaux éléments aux clients. A chaque livraison, l’équipe de développement fera en sorte de livrer des tronçons complets pour ne pas donner l’impression de travail inachevé. Elle introduira également les retours sur la version précédente dans la mesure de ce qui a été convenu.

La stratégie :
Si l’objectif est d’améliorer l’expérience utilisateur, et de livrer quelque chose de visible tous les mois, il faut être efficace. Dans ces conditions, pas question de remplacer le vieux framework MVC maison par un standard du marché : la valeur ajoutée utilisateur est proche de zéro.
Inutile non plus de tenter une migration vers le dernier framework de développement RIA, genre GWT ou Flex. Cela ne serait pas compatible avec la démarche définie ci-dessus… et les risques de régressions fonctionnelles sont énormes, surtout s’il existe du code métier dans les pages faisant le rendu HTML, ce qui est fréquent !

Une stratégie à la fois raisonnable et efficace est de transformer progressivement l’application en remplaçant certains éléments existants, ou bien en ajoutant de nouveaux éléments. Pour cela, il faut choisir une librairie Javascript suffisamment riche pour :
  • Proposer nativement des éléments graphiques comme des fenêtres modales, des datepickers, des accordéons, onglets, etc.
  • Manipuler dynamiquement les éléments du document au travers de sélecteurs
  • Mettre en place facilement des appels AJAX
  • Permettre la création de plugins (pour pouvoir en réutiliser !).

La bibliothèque jQuery est particulièrement adaptée pour ce type de réalisation, car elle a un excellent équilibre entre sa valeur ajoutée intrinsèque et son niveau d’intrusion lorsqu’elle est insérée dans une application existante. Il faut dire qu’avec seulement quelques fichiers .js et .css à inclure (si l’on adjoint jQuery UI), il est difficile de faire moins intrusif ! De plus la clarté de sa documentation et la quantité de blogs de développeurs s’y référant rendent sa mise en œuvre rapide.

La mise en œuvre :
Voici quelques idées de transformations simples qui ont un impact immédiat :
  • Remplacement d’anciens calendriers s’ouvrant dans une fenêtre popup (utilisation du composant datepicker de jQuery)
  • Utilisation de tables triables et paginées dès que le nombre d’éléments à afficher dépasse quelques dizaines. Utilisation de cookies pour enregistrer ordres les tris et les choix de pagination
  • Utilisation du drag and drop pour sélectionner quelques éléments parmi une liste
  • Création d’un espace dans lequel l’utilisateur peut personnaliser l’application : choix d’un thème, des options de l’application,
  • Ajout d’un composant affichant en temps réel la complexité du mot de passe utilisateur lorsqu’il est modifié
  • Suppression des fenêtres popups qui compliquent la navigation (utilisation du composant dialog de jQuery)
  • Utilisation d’appels AJAX lorsqu’il faut mettre à jour une très faible quantité d’informations sur une page. Dans ce cas, retourner soit des chaînes de caractères pour du texte, soit un objet JSON pour des tableaux ou des objets structurés.
  • Restructurer les pages trop denses soit en les découpant, soit en utilisant des composants comme les onglets ou les accordéons
  • Dans les formulaires, ramener les contrôles de format sur le client : taille maximale, formats numériques, monétaires, codes postaux, etc. Cela évitera des rechargements de pages en cas d’erreurs de saisie
  • Valider que la navigation au clavier est opérationnelle dans tous les formulaires de saisie,
  • Dans les formulaires encore, ajout d’aides à la saisie, comme le format attendu d’une date, d’un n° de téléphone, ou encore le nombre de caractères restant lors d’une saisie dans une textarea.
  • Lors d’une erreur de saisie dans un formulaire, indiquer clairement dans quel champ se situe l’erreur, et quelle est la nature de l’erreur. Mettre bien évidemment le focus sur ce champ.

Lors de la mise en œuvre, le responsable des développements devra garder en tête que ce sont les petits ruisseaux qui font les grands fleuves…