Authentification: utilisation JWT vs session

122

Quel est l'avantage d'utiliser les JWT par rapport aux sessions dans des situations telles que l'authentification?

Est-il utilisé comme une approche autonome ou est-il utilisé dans la session?

Pourya8366
la source

Réponses:

213

JWT n'a aucun avantage par rapport à l'utilisation de "sessions" en soi. Les JWT fournissent un moyen de maintenir l'état de session sur le client au lieu de le faire sur le serveur.

Ce que les gens veulent souvent dire en posant cette question est "Quels sont les avantages de l'utilisation des JWT par rapport à l'utilisation des sessions côté serveur "

Avec les sessions côté serveur, vous devrez soit stocker l'identifiant de session dans une base de données, soit le conserver en mémoire et vous assurer que le client atteint toujours le même serveur. Les deux ont des inconvénients. Dans le cas de la base de données (ou d'un autre stockage centralisé), cela devient un goulot d'étranglement et une chose à maintenir - essentiellement une requête supplémentaire à effectuer avec chaque demande.

Avec une solution en mémoire, vous limitez votre mise à l'échelle horizontale, et les sessions seront affectées par des problèmes de réseau (clients itinérants entre Wifi et données mobiles, redémarrage des serveurs, etc.)

Déplacer la session vers le client signifie que vous supprimez la dépendance sur une session côté serveur, mais cela impose son propre ensemble de défis.

  • Stocker le jeton en toute sécurité
  • le transporter en toute sécurité
  • Les sessions JWT peuvent parfois être difficiles à invalider.
  • Faire confiance à la réclamation du client.

Ces problèmes sont partagés par les JWT et d'autres mécanismes de session côté client.

JWT en particulier aborde le dernier d'entre eux. Il peut être utile de comprendre ce qu'est un JWT:

C'est un peu d'information. Pour les sessions utilisateur, vous pouvez inclure le nom d'utilisateur et l'heure à laquelle le jeton expire. Mais cela pourrait être n'importe quoi, même l'ID de session ou le profil complet de l'utilisateur. (Veuillez ne pas le faire cependant) Il a une signature sécurisée qui empêche les parties malveillantes de générer de faux jetons (vous devez accéder à la clé privée du serveur pour les signer et vous pouvez vérifier qu'ils n'ont pas été modifiés après leur signature) envoyez-les avec chaque demande, tout comme un cookie ou un en- Authorizationtête serait envoyé. En fait, ils sont généralement envoyés dans l'en- Authorizationtête HTTP, mais l'utilisation d'un cookie convient également.

Le jeton est signé et le serveur peut donc vérifier son origine. Nous supposerons que le serveur fait confiance à sa propre capacité à signer en toute sécurité (vous devez utiliser une bibliothèque standard: n'essayez pas de le faire vous-même et sécurisez le serveur correctement)

En ce qui concerne le transport sécurisé du jeton, la réponse est généralement de l'envoyer via un canal crypté, généralement httpS.

En ce qui concerne le stockage sécurisé du jeton dans le client, vous devez vous assurer que les méchants ne peuvent pas y accéder. Cela (principalement) signifie empêcher JS des mauvais sites Web de lire le jeton pour le leur renvoyer. Ceci est atténué en utilisant les mêmes stratégies que celles utilisées pour atténuer d'autres types d'attaques XSS.

Si vous avez besoin d'invalider les JWT, il existe certainement des moyens d'y parvenir. Stocker une époque par utilisateur uniquement pour les utilisateurs qui ont demandé que leurs «autres sessions se terminent» est une méthode très efficace qui sera probablement suffisante. Si une application nécessite une invalidation par session, alors un ID de session peut être conservé de la même manière et la table des "jetons tués" peut toujours être maintenue pour être beaucoup plus petite que la table utilisateur complète (il vous suffit de conserver les enregistrements plus récents que le la plus longue durée de vie autorisée du jeton.) Ainsi, la possibilité d'invalider le jeton annule partiellement l'avantage des sessions côté client dans la mesure où vous auriez à maintenir cet état de session interrompue. Ce sera probablement une table beaucoup plus petite que la table d'état de session d'origine, donc les recherches sont encore plus efficaces.

Un autre avantage de l'utilisation des jetons JWT est qu'il est raisonnablement facile à implémenter en utilisant des bibliothèques disponibles dans probablement toutes les langues auxquelles vous pouvez vous attendre. Il est également complètement séparé de votre schéma d'authentification utilisateur initial - si vous passez à un système basé sur les empreintes digitales, vous n'avez pas besoin de modifier le schéma de gestion de session.

Un avantage plus subtil: étant donné que le JWT peut transporter des «informations» et que le client peut y accéder, vous pouvez maintenant commencer à faire des choses intelligentes. Par exemple, rappelez à l'utilisateur que sa session expirera quelques jours avant sa déconnexion, en lui donnant la possibilité de s'authentifier à nouveau, en fonction de la date d'expiration du jeton. Tout ce que vous pouvez imaginer.

Donc, en bref: les JWT répondent à certaines des questions et des lacunes d'autres techniques de session.

  1. Authentification "moins chère" car vous pouvez éliminer un aller-retour DB (ou au moins avoir une table beaucoup plus petite à interroger!), Qui à son tour permet une évolutivité horizontale.
  2. Réclamations infalsifiables côté client.

Bien que JWT ne réponde pas aux autres problèmes tels que le stockage ou le transport sécurisé, il n'introduit aucun nouveau problème de sécurité.

Il existe beaucoup de négativité autour des JWT, mais si vous implémentez la même sécurité que vous le feriez pour d'autres types d'authentification, tout ira bien.

Une dernière remarque: il ne s'agit pas non plus de cookies vs jetons. Les cookies sont un mécanisme de stockage et de transport de bits d'informations et peuvent également être utilisés pour stocker et transporter des jetons JWT.

Le Tahaan
la source
4
Il convient de noter que les sessions côté serveur n'ont pas non plus à stocker d'informations sur le serveur. Le serveur peut utiliser le client comme magasin de la même manière que le fait le JWT. La vraie différence réside dans 1) éviter les règles de sécurité du navigateur en passant la valeur comme en-tête de demande autre qu'un en-tête de cookie, et 2) avoir un format standardisé avec JWT.
Xeoncross
1
Diriez-vous qu'il est sûr de stocker un jwt dans le stockage local? Sinon, où est un endroit sûr pour le sauvegarder afin que l'utilisateur reste connecté?
Jessica le
1
Oui, localstorage est généralement l'endroit le plus approprié pour le stocker côté client. Vous devez traiter avec XSS - Je ne suis pas un expert en programmation Web, mais regardez cette réponse stackoverflow.com/a/40376819/1810447 et recherchez "Comment se protéger contre XSS"
The Tahaan
1
Dans votre commentaire, vous ne parlez pas de solution basée sur le cache + jeton de session. Cela me semble "meilleur" que la table JWT + "jetons tués", car avec cette table "jetons tués", vous avez de toute façon besoin d'un accès à la base de données, que vous aurez aussi avec sessions + cache (qui est petit aussi). Et le JWT persistant est plus pénible à implémenter que les sessions persistantes, car vous devez jouer avec un refresh_token (donc deux jetons à maintenir) ... Tout commentaire serait vraiment apprécié ... surtout si vous avez un certain nombre pour montrer comment JWT + kill_table est plus efficace que les sessions + cache ;-)
tobiasBora
2
@TheTahaan localStorage n'est pas recommandé pour stocker les JWT. Le lien que vous avez partagé le mentionne également. Ce blog explique pourquoi JWT ne doit pas être stocké dans localStorage.
Harke
40

La réponse courte est: aucune.

Une version plus longue est:

J'ai implémenté des JWT pour la gestion de session après avoir lu cette recommandation dans la documentation GraphQL :

Si vous n'êtes familier avec aucun de ces mécanismes d'authentification, nous vous recommandons d'utiliser express-jwt car c'est simple sans sacrifier aucune flexibilité future.

La mise en œuvre était en effet simple car elle ne faisait qu'ajouter un peu de complexité. Après un certain temps cependant, j'ai (comme vous) commencé à me demander quels étaient les avantages. Il s'avère qu'il y en a très peu (ou peut-être aucun) pour JWT en ce qui concerne la gestion de session, comme ce billet de blog l'explique en détail:

Arrêter d'utiliser JWT pour les sessions

Carl von Blixen
la source
0

Mes deux cents, qui sur le chemin ajoutent un peu de contraste au célèbre article de blog de joepie91.

Étant donné que les applications d' aujourd'hui (et de demain) sont (pour la plupart) natives du cloud
Il y a un avantage économique à l' authentification JWT sans état , qui évolue à mesure que l'application évolue: les
applications cloud entraînent des coûts à chaque respiration .
Ce coût est réduit lorsque les utilisateurs n'ont plus à s'authentifier «auprès» d'un magasin de sessions.

Traitement L'
exécution d'un magasin de session 24/7 coûte de l'argent.
Vous ne pouvez pas vous en sortir avec des solutions basées sur la mémoire dans le monde de K8S, car les pods sont éphémères.
Les sessions collantes ne fonctionneront pas bien pour la même raison.

Stockage Le
stockage des données coûte de l'argent. le stockage des données dans un SSD coûte encore plus cher.
Les opérations liées à la session doivent être résolues rapidement, un lecteur optique n'est donc pas une option.

E / S
Certains fournisseurs de cloud facturent de l'argent pour les E / S liées au disque.

Bande passante
Certains fournisseurs de cloud facturent l'activité réseau entre les instances de serveur.
Cela s'applique car il est presque certain que l'API et le magasin de sessions sont des instances distinctes.

Clustering du magasin de sessions
Le coût augmente encore plus tous les coûts mentionnés ci-dessus.

Eyal Perry
la source
"Vous ne pouvez pas vous en sortir avec des solutions basées sur la mémoire dans le monde de K8S, car les pods sont éphémères" Je ne sais pas ce que vous entendez par là. Redis fonctionne définitivement dans un environnement K8S, et un pod Redis échouant suffisamment souvent pour affecter vos utilisateurs semble très improbable.
quietContest
@quietContest Personnellement, je préfère ne pas gérer la probabilité lors de la création de logiciels. BTW, mise à part la stabilité de la solution, une attaque peut provoquer l'échec du logiciel et le redémarrage des pods, ce qui entraînerait une perte de session. J'opterais pour une solution basée sur JWT pour cette raison.
Eyal Perry le
1
"Personnellement, je préfère ne pas gérer la probabilité lors de la création de logiciels". Je pense que nous préférerions tous cela, c'est pourquoi nous ne devrions pas concevoir des systèmes qui reposent sur des magasins de données en mémoire qui ne tombent jamais en panne, car la probabilité que cela semble raisonnablement élevé. Quant à votre autre point, si vous avez un attaquant qui est capable de fermer systématiquement votre instance redis, la solution à cela n'a probablement pas besoin d'impliquer l'utilisation de JWT.
quietContest
@quietContest régulièrement ou un événement unique dans ma vie sont les mêmes pour moi dans cet aspect. c'est-à-dire qu'une attaque DDoS bien placée peut amener le serveur à "déconnecter les utilisateurs". Cela ne fait pas bon pour la réputation de fiabilité du logiciel. Je pense que redis est de toute façon excessif pour la gestion de session. Cela coûte et doit être mis à l'échelle, contrairement au stockage (en toute sécurité) d'un JWT dans un cookie.
Eyal Perry le
1
@quietContest merci pour votre contribution, adorez la discussion!
Eyal Perry le
0

J'avais une question similaire en choisissant entre JWT et token + cache pour l'authentification des utilisateurs.

Après avoir lu ces articles, il est clair pour moi que les avantages promis par JWT ne dépassent pas les problèmes qu'il apporte. Donc, token + cache (Redis / Memcached) est la voie à suivre pour moi.

En-têtes d'authentification vs JWT vs sessions - Comment choisir la bonne technique d'authentification pour les API

Techniques d'authentification pour les API

Arrêtez d'utiliser jwt pour les sessions

h - n
la source