Meilleures pratiques pour invalider JWT tout en changeant les mots de passe et la déconnexion dans le noeud.js? [fermé]

je voudrais connaître les meilleures pratiques pour invalider JWT sans frapper db tout en changeant mot de passe/déconnexion.

j'ai l'idée ci-dessous pour gérer plus de 2 cas en frappant la base de données des utilisateurs.

1.En cas de changement de mot de passe, je vérifie le mot de passe(hashé) stocké dans la base de données de l'utilisateur.

2.En cas de déconnexion, je sauve le temps de la dernière déconnexion dans la base de données de l'utilisateur, donc en comparant le temps de création du jeton et le temps de déconnexion, je peux invalider cette affaire.

mais ces 2 cas vient au coût de frapper l'utilisateur db chaque fois que l'utilisateur frappe l'api. Toute pratique exemplaire est appréciée.

mise à JOUR: Je ne pense pas qu'on puisse invalider JWT sans frapper db. Donc, je suis venu avec une solution. J'ai posté ma réponse, si vous avez le moindre souci, vous êtes les bienvenus.

51
demandé sur Gopinath Shiva 2015-02-27 10:20:34

5 réponses

Lorsqu'Aucun Jeton de rafraîchissement n'est utilisé:

1.Lors du changement de mot de passe: lorsque l'utilisateur change son mot de passe, notez le temps de changement de mot de passe dans la base de données de l'utilisateur, donc lorsque le temps de changement de mot de passe est supérieur au temps de création du token, alors le token n'est pas valide. Par conséquent, la session restante sera bientôt déconnectée.

2.Lorsque l'Utilisateur se déconnecte: Lorsque l'utilisateur se déconnecte, enregistrez le jeton dans un DB séparé (par exemple: InvalidTokenDB et supprimer le jeton de Db lorsque le jeton expire). Par conséquent, l'utilisateur se déconnecte du périphérique respectif, ses sessions dans un autre périphérique ne sont pas perturbées.

ainsi, tout en invalidant une JWT, je suis les étapes suivantes:

  1. vérifiez si le jeton est valide ou non.
  2. si valide, vérifiez qu'il est présent dans invalidTokenDB (une base de données où les tokens déconnectés sont stockés jusqu'à leur expiration temps.)
  3. si elle n'est pas présente, alors vérifiez l'Heure de création du token et l'heure du mot de passe changé dans l'utilisateur db.
  4. si le mot de passe a été modifié < token created time, alors token est valide.

Souci avec la méthode ci-dessus :

  1. pour chaque requête api, je dois suivre toutes les étapes ci-dessus, qui pourraient affecter les performances.

lorsque le jeton de rafraîchissement est utilisé: avec l'expiration du jeton d'accès à 1 jour, le jeton de rafraîchissement à vie

1. En changeant le mot de passe: lorsque l'utilisateur change son mot de passe, Changez le jeton de rafraîchissement de l'utilisateur. Par conséquent, la session restante sera bientôt déconnectée.

2. Lorsque L'utilisateur se déconnecte : lorsque l'utilisateur se déconnecte, enregistrez le token dans un DB séparé (par exemple: InvalidTokenDB et supprimer le token de Db quand le token expire). Par conséquent, l'utilisateur se déconnecte du périphérique respectif, ses sessions dans un autre périphérique ne sont pas perturbées.

ainsi, tout en invalidant une JWT, je suis les étapes suivantes:

  1. vérifier si le jeton est valide ou non
  2. si valide, vérifier si le jeton est présent dans InvalidTokenDB.
  3. si vous n'êtes pas présent, vérifiez le jeton refresh avec le jeton refresh dans userbd.
  4. si égal, alors c'est un jeton valide

Souci avec la méthode ci-dessus :

  1. pour chaque requête api, je dois suivre toutes les étapes ci-dessus, qui pourraient affecter les performances.
  2. comment invalider le token de rafraîchissement, car le token de rafraîchissement n'a pas de validité, si son utilisé par le hacker, encore l'authentification est valide un, la requête sera toujours un succès.

Note : bien que Hanz ait suggéré un moyen de sécuriser le jeton refresh dans en utilisant le jeton Refesh dans L'authentification basée sur un jeton est-il sécurisé? , Je ne pouvais pas comprendre ce qu'il disait. Toute aide est appréciée.

donc si quelqu'un a de bonnes suggestions, vos commentaires sont les bienvenus.

mise à JOUR: J'ajoute la réponse au cas où votre application n'a pas besoin de rafraîchir le jeton avec l'expiration à vie. Cette réponse a été donnée par Sudhanshu ( https://stackoverflow.com/users/4062630/sudhanshu-gaur ). Merci Sudhanshu. Donc, je crois que c'est la meilleure façon de le faire,

Lorsqu'Aucun Jeton de rafraîchissement n'est nécessaire et qu'il n'y a pas d'expiration des jetons d'accès:

lorsque l'utilisateur se connecte, créer un token de connexion dans sa base de données utilisateur sans délai d'expiration.

Par conséquent, tout en invalidant une JWT, suivre les étapes ci-dessous,

  1. récupérez les informations utilisateur et vérifiez si le token est dans sa base de données utilisateur. Si le permettent.
  2. lorsque l'utilisateur se déconnecte, supprimez seulement ce token de sa base de données utilisateur.
  3. lorsque l'utilisateur change son mot de passe, supprimez tous les jetons de sa base de données et demandez-lui de se connecter à nouveau.

Donc, avec cette approche, vous n'avez pas besoin de stocker ni les tokens de déconnexion dans la base de données jusqu'à leur expiration, ni le stockage du temps de création des tokens en changeant le mot de passe qui était nécessaire dans les cas ci-dessus. Cependant, je crois que cette approche valid seulement si votre application a des exigences sans jeton de rafraîchissement nécessaire et aucune expiration des jetons.

si quelqu'un est préoccupé par cette approche, veuillez me le faire savoir. Vos commentaires sont les bienvenus :)

58
répondu Gopinath Shiva 2017-05-23 10:31:17

Je ne connais aucun moyen d'invalider arbitrairement un token sans impliquer une base de données d'une manière ou d'une autre.

soyez prudent avec L'approche 2 si votre service peut être consulté sur plusieurs appareils. Envisagez le scénario suivant...

  • L'utilisateur se connecte à l'iPad, jeton 1 émis et enregistré.
  • L'utilisateur s'inscrit sur le site web. Jeton 2 émis. L'utilisateur se déconnecte.
  • l'utilisateur essaie de utilisez iPad, le jeton 1 a été émis avant que l'utilisateur se soit déconnecté du site web, le jeton 1 est maintenant considéré comme invalide.

vous pourriez vouloir regarder l'idée de rafraîchir des jetons bien que ceux-ci nécessitent un stockage de base de données aussi.

Voir aussi ici pour une bonne discussion sur un problème similaire, en particulier la solution de IanB qui permettrait d'enregistrer quelques appels db.

solution proposée Personnellement, c'est comme ça que je l'aborderais...l'utilisateur authentifie, avec un jeton d'accès avec une courte échéance (disons 15 minutes) et un jeton de rafraîchissement valide soit pour une période beaucoup plus longue ou indéfiniment. Enregistrez un enregistrement de ce jeton de rafraîchissement dans un db.

Chaque fois que l'utilisateur est "actif", un nouveau jeton d'authentification à chaque fois (valable 15 minutes à chaque fois). Si l'utilisateur n'est pas actif pendant plus de 15 minutes et puis fait une demande (utilise JWT), vérifiez la validité du jeton de rafraîchissement. Si elle est valide (y compris la vérification db), alors lancez un nouveau jeton auth.

si un utilisateur 'se déconnecte' sur un périphérique ou via un site web, alors détruisez à la fois les tokens access refresh côté client et révoquez de manière importante la validité du token refresh utilisé. Si un utilisateur change son mot de passe sur n'importe quel périphérique, alors révoquez tous leurs tokens de rafraîchissement les forçant à se connecter de nouveau dès que leur token d'accès expire. Cela laisse une 'fenêtre d'incertitude' mais c'est inévitable sans frapper un db à chaque fois.

L'utilisation de cette approche ouvre également la possibilité pour les utilisateurs de pouvoir "révoquer" l'accès à des appareils spécifiques si nécessaire, comme le montrent de nombreuses applications web majeures.

13
répondu DevFox 2017-05-23 12:17:59

Je ne suis pas sûr de manquer quelque chose ici, mais je trouve que la réponse acceptée est plus compliquée qu'il n'est nécessaire.

je vois que db doit être cliqué pour valider ou invalider un token pour chaque requête api, cependant le processus total aurait pu être plus simple comme je vois les choses ici.

chaque fois qu'une jwt est créée, c'est-à-dire lors de la connexion ou du changement/réinitialisation du mot de passe, insérez la jwt avec userid dans une table et maintenez un numéro jti (uuid fondamentalement) pour chaque jwt. Le même jti va dans la charge utile jwt aussi. Effectivement, l'ITC identifie de façon unique une ELT. Un utilisateur peut avoir plusieurs JWT en même temps lorsque le compte est accédé à partir de plusieurs appareils ou navigateurs, auquel cas, jti différencie l'appareil ou l'agent utilisateur.

donc le schéma de la table serait, jti / userId. (et une clé primaire bien sûr)

Pour chaque api, vérifiez si l'itc est dans le tableau, ce qui signifie que le jwt est valide.

lorsque l'utilisateur change ou réinitialise le mot de passe, supprimez tous les jti de cet userId de la base de données. Créer et insérer une nouvelle jwt avec une nouvelle jti dans le tableau. Cela invalidera toutes les sessions de tous les autres appareils et navigateurs à l'exception de celui qui a changé ou réinitialisé le mot de passe.

lorsque l'utilisateur se déconnecte, supprimer ce jti particulier de cet utilisateur, mais pas tous. Il n'y aurait qu'une seule connexion, mais pas une seule déconnexion. Ainsi, lorsque l'utilisateur se déconnecte, il ne devrais pas être déconnecté de tous les appareils. Cependant, la suppression de toutes les ITC entraînerait la déconnexion de tous les appareils.

donc ce serait une table et aucune comparaison de date. Aussi, il serait le même cas si un jeton d'actualisation est utilisé ou non.

Cependant pour minimiser l'interférence db, et les retards possibles, l'utilisation de cache aiderait certainement à faciliter les choses sur le temps de traitement avant.

Note: prière de justifier si vous votez contre.

6
répondu Amruta-Pani 2016-12-06 07:45:50

si un utilisateur change son mot de passe, vous allez frapper la base de données là. Mais vous ne voulez pas frapper le db pour l'autorisation?

j'ai trouvé les avantages de stocker une chaîne par utilisateur, et une chaîne partagée mondiale hachée ensemble nous donne la plus de flexibilité avec notre implémentation JWT. Dans ce cas particulier, je stockerais un hachage du mot de passe à utiliser avec la chaîne globale et les hachage ensemble pour un secret JWT.

1
répondu Mark Essel 2016-08-30 15:04:43

je suis d'accord uniquement avec la réponse @gopinath juste pour ajouter une chose que vous devriez également supprimer le temps de changement de mot de passe lorsque tous vos tokens ont expiré par exemple supposons que vous avez défini 3 jours de temps d'expiration pour chaque token à expirer maintenant au lieu de simplement sauver normaly le temps de changement de mot de passe dans la base de données, vous pouvez également définir son temps d'expiration de 3 jours parce que comme évidemment les tokens avant ce sera expiré, donc pas besoin de vérifier pour chaque token à nouveau que si son temps d'expiration est plus grand que changer l'heure du mot de passe ou pas

-1
répondu Sudhanshu Gaur 2016-01-11 17:32:55