31/10/2018 Tech
Introduction aux JSON Web tokens
L’authentification est une problématique récurrente du développement d’applications web et mobile.
Dans un monde où les API sont consommées par toutes sortes de clients (navigateurs, applications natives mobile, …), il est important de pouvoir offrir une solution commune performante et sécurisée.
Historiquement, pour remplir ce rôle, les cookies sont utilisés et retournés par le serveur au client suite à une authentification réussie. Ces mêmes cookies accompagnent chaque requête du client afin de l’identifier. Les sessions sont maintenues côté serveur (stockées en mémoire, sur le file-system ou encore en base de données) avec par conséquent une problématique de charge à gérer.
D’autres solutions existent telles que HTTP Basic Authentication (les identifiants de l’utilisateur doivent cependant transiter dans chaque requête).
Avec les applications mobiles natives, la gestion des cookies est relativement fastidieuse et les problématiques de Cross-origin resource sharing (CORS) récurrentes. Ajoutez à cela qu’une API REST se doit d’être stateless (pas de session côté serveur).
Web tokens
Les web tokens sont une alternative intéressante. Le principe est simple, après s’être authentifié, le serveur génère un hash de plus de 100 caractères qui servira de signature pendant une certaine durée. Ce token va ensuite transiter dans chaque requête entre le client et le serveur. Pas de cookie ni de session serveur. De plus, cette solution est applicable pour tout type de plateforme et peut permettre à une API d’être utilisée par des applications natives, des applications web…
On a la possibilité de générer un token différent pour chaque requête, on peut donc aussi se protéger contre les attaques de type CSRF (Cross-Site Request Forgery) à savoir l’usurpation d’identité.
JWT
Il existe un draft de spécification concernant les JWT (JSON Web Tokens) prononcé “jot”. Un JWT est simplement constitué de trois parties séparées par un point : part1.part2.part3.
part1 : Le header encodé en base64
Le header contient un objet javascript indiquant l’algorithme utilisé pour “hasher” le contenu.
Exemple : { “typ”: “JWT”, “alg”: “HS256” } ⇒ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 (en base64)
part2 : Le contenu encodé en base64 (JWT claims)
Le contenu est un simple objet avec les informations à échanger entre le client et le serveur (expiration du token, identité de l’utilisateur connecté, …). On peut y placer librement des champs personnalisés et propres à nos besoins (public claims) et des attributs réservés définis dans la spécification (registered claims).
Quelques “registered claims” :
- iss : Origine du token (issuer),
- sub : Sujet (subject),
- exp : Date d’expiration du token (expiration),
- iat : Date de création du token (issued at),
- …
Exemple : { “iss”: “ekino.com”, “name”: “John Doe”, “admin”: true } ⇒ eyAiaXNzIjogImVraW5vLmNvbSIsICJuYW1lIjogIkpvaG4gRG9lIiwgImFkbWluIjogdHJ1ZSB9 (en base64)
part3 : La signature
Pour générer la signature, on concatène le header et le contenu puis on encode avec l’algorithme défini dans le header.
Exemple :
HMACSHA256(
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 + “.” + eyAiaXNzIjogImVraW5vLmNvbSIsICJuYW1lIjogIkpvaG4gRG9lIiwgImFkbWluIjogdHJ1ZSB9,
“secret key”
)
JWT permet donc d’échanger du contenu pour un utilisateur authentifié grâce à la clé secrète utilisée dans la signature. La signature permet également d’assurer l’intégrité du contenu.
JSON web token récupéré et échangé entre le client et le serveur
Dans la pratique
JWT.IO
Le site http://jwt.io maintenu par Auth0 propose un debugger permettant de décoder un JWT. Ce site liste également les différentes librairies à utiliser côté serveur pour générer les tokens (.Net, Python, NodeJS, Java, PHP, Ruby, Go, JS, …).
Angular JWT
Également maintenu par Auth0, le projet est sur GitHub.
Grâce à ce module Angular, il est possible de :
Décoder les JWT simplement dans les applications AngularJS,
Vérifier les dates d’expiration des tokens automatiquement,
Automatiser l’envoi des tokens JWT avec un intercepteur pour chaque requête.
Conclusion
Cette approche à l’avantage de pouvoir être utilisée avec de nombreuses technologies. Les tokens s’auto-suffisent, ils contiennent toute l’information nécessaire à l’identification d’un utilisateur. Ils peuvent aussi bien être utilisés dans une URL que dans un header HTTP.
Sources :
- http://jwt.io
- http://angular-tips.com/blog/2014/05/json-web-tokens-introduction
- http://www.sitepoint.com/using-json-web-tokens-node-js
- http://websec.io/2014/08/04/Securing-Requests-with-JWT.html
- https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
- https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries
Crédit photo : startupstockphotos.com