:::: MENU ::::

Gérer l’authentification d’une application Web

Dans le cadre d’une page ou d’une application web du type Single Page Application ( SPA ) peut se poser la problématique de l’authentification. Au delà de l‘identification  HTTP, nous verrons ce qu’il est possible de mettre en place coté serveur et client pour gérer l’authentification d’un utilisateur en se basant sur ExpressJs pour le serveur et AngularJs pour le client.

Cet article est le premier d’une série consacrée à l’authentification d’une application Web .

Les bases de l’authentification web

Sécuriser une SPA partie1, le serveur avec expressJS

Sécuriser une SPA partie2, le client sous AngularJs

Une question de workflow

La grande différence entre une application web standard et une SPA réside dans le workflow des requêtes client / server du processus d’authentification .

Application web standard

 

WorkFlow WebApp

SPA

WorkFlow SPA

Dans le cas d’une application traditionnelle, le client se contente d’afficher le html généré par le serveur alors que pour une SPA, le serveur renvoie le minimum d’informations et c’est le client qui construit l’IHM en fonction de l’état de l’application.  Le client réagit donc aux données renvoyées et aux codes d’erreurs.

A noter que pour une SPA le contrôle d’accès d’une ressource doit se faire à la fois coté client et serveur. Le serveur doit protéger les appels à son API et le client ne doit pas permettre à un utilisateur non autorisé l’affichage d’un panneau d’admin par exemple.

Technique traditionnelle : sessions et cookies

Le mécanisme des sessions permet de conserver temporairement une trace de l’utilisateur. En effet, le HTTP étant un protocole dit « sans état » , le serveur traite les requêtes sans garder de traces des précédentes.

Le principe est simple : lorsqu’on établit une première connexion avec le serveur, on se voit attribuer un identifiant de session, par la suite, cet identifiant sera renvoyé au serveur à chaque requête et permettra une association avec un utilisateur.

Pour stocker cette session, client et serveur ont différentes possibilités. Dans un premier temps, coté serveur, on conservera notre session en mémoire. C’est le cas le plus simple mais déconseillé en production ( en effet, si le nombre de sessions augmente, la mémoire aussi.. ) .

La session peut être stockée dans une base clé-valeurs tel que Redis pour optimiser les performances .

Coté client, il y a deux grandes méthodes pour gérer les sessions : les cookies ou le Webstorage . L’avantage d’utiliser les techniques de localStorage ou sessionStorage c’est qu’elles permettent de stoker plus d’informations que les cookies.

Les Cookies

cookies

 Bien obligé de faire la blague habituelle, nos bon vieux cookies sont toujours comestibles. Pour rappel ce sont de simples fichiers texte non executables et bien qu’ils ne soient pas limités à cet usage, on s’en sert souvent pour les questions de sessions. Voyons comment les utiliser simplement avec ExpressJs à travers cet exemple.

var express = require("express"),
session = require("cookie-session"),
app = express();

app.use(session({
 keys: ["maclé"]
}));

app.get("/",function (req, res, next) {
 var n = req.session.views || 0;
 req.session.views = ++n;
 res.end(n + " vues");
});

app.listen(3000);

 

 

Voyons ce qu’il se passe d’un peu plus prêt en utilisant l’inspecteur de ressource de chrome :

et hop un cookie de session

Si on creuse un peu plus sur les requêtes réseau :

Lors de la première connexion on peut remarquer que le serveur envoie un set-Cookie . Le navigateur enregistre un cookie qui contient les données de session.

On rafraîchi la page :

Le client renvoie les données du cookie, le serveur le reconnait. Une session est bien établie, notre connexion est devenu Stateful !

 

Sécurisation par Tokens ( jetons )

Une autre méthode souvent utilisée notamment dans les services web est celle des tokens ou jetons. La technique est un peu différente car on ne cherche pas à conserver une session entre le client et le serveur ( l’authentification par token est donc Stateless ) .

Pour bien comprendre la différence voici une illustration de connexion d’un utilisateur avec les sessions et son équivalent avec les jetons.

Authentification par Session

Cookie-based Auth

 

Authentification par Jetons

Token-based Auth

 

Le serveur ne conserve rien dans le cas des jetons. Il va simplement décoder le code renvoyé par le client au format JWT  ( Json Web Token ) et vérifier qu’il est valide.

JWT pour faire court est une spécification qui décrit une norme de jeton issu d’un objet en json qu’on aura haché, éventuellement crypté puis encodé en base64

Avantage des Jeton par rapport aux cookies

Même si les deux schémas semblent similaires, il y a des avantages à utiliser les jetons plutot que les cookies :

Plus grand découplage possible

Le système de session implique de conserver une trace de l’utilisateur sur le serveur. Or avec les jetons et leur aspect « Stateless », le découplage entre client et serveur est totalement clair, la scalabilité s’en voit fortement améliorée. C’est la raison pour laquelle il est plus simple de mettre en place un service Web basé sur les jetons en déportant la gestion de l’authentification sur une autre plate forme par exemple car le Cross Domain est compliqué avec des cookies .

Protection contre les attaques CSRF

Une attaque dite CSRF ( Cross-Site Request Forgery ) consiste à se servir des données de session de l’utilisateur attaqué pour contourner une protection. Supposons que l’attaquant connaisse un lien appelant une action de suppression d’article sur un blog par exemple, s’il tente d’effectuer l’action, le serveur lui demandera de s’authentifier. Si maintenant, il envoie ce lien (généralement caché ) à une personne enregistrée sur le serveur ( autrement dit possédant une session en cours ) , alors l’action s’effectuera au nom de l’utilisateur attaqué.

Puisque les jetons sont générés à la volé et vérifiés par le serveur, on ne peut pas utiliser de session pour accéder à des ressources protégées. Cela ne veut pas dire pour autant que les jetons seuls fournissent une sécurité parfaite loin de là, mais on évite au moins ce genre d’attaques.

Meilleurs performances

Du fait que l’on ne va pas chercher de données de sessions ( en base ou ailleurs ) on peut gagner en performance. Cela se fera surtout sentir sur de grosses architectures .

Intégration mobile facilitée

Avec les jetons, pas besoin de compatibilité de navigateur (WebStorage cookie & Co ) puisque pas de session !

 

Jetons les cookies !?

Si le systeme d’authentification par token fait réver, nos bon vieux cookies ont toujours raison d’exister. Cela dépend de l’utilisation mais un des gros problèmes du systeme par token, c’est qu’il est par principe, sans état. Or c’est précisemment ce qu’on a besoin lorsqu’on fait une application web. Le cas où les jetons prennent tous leur sens, c’est lorsqu’il s’agit d’un service web. Autrement dit, la partie purement API.

Cookies vs Jetons

Pour résumer :

On utilisera un système de session basé sur les cookies pour faire une application web

On préférera une authentification par jetons dans le cadre d’un service web

 

La suite

Maintenant qu’on a fait le point sur les bases, on va commencer à construire notre application web en commençant par le serveur .

 


5 Comments

So, what do you think ?