Je construis une API RESTful qui utilise des jetons JWT pour l'authentification des utilisateurs (émise par un login
point de terminaison et envoyée dans tous les en-têtes par la suite), et les jetons doivent être actualisés après un laps de temps fixe (invocation d'un renew
point de terminaison, qui renvoie un jeton renouvelé ).
Il est possible que la session API d'un utilisateur devienne invalide avant l'expiration du jeton.Par conséquent, tous mes points de terminaison commencent par vérifier que: 1) le jeton est toujours valide et 2) la session de l'utilisateur est toujours valide. Il n'y a aucun moyen d'invalider directement le jeton, car les clients le stockent localement.
Par conséquent, tous mes points de terminaison doivent signaler à mes clients deux conditions possibles: 1) qu'il est temps de renouveler le jeton ou 2) que la session est devenue invalide et qu'ils ne sont plus autorisés à accéder au système. Je peux penser à deux alternatives pour mes points d'extrémité pour signaler à leurs clients lorsqu'une des deux conditions se produit (supposons que les clients peuvent être adaptés à l'une ou l'autre option):
- Renvoyez un code http 401 (non autorisé) si la session est devenue invalide ou renvoyez un code 412 (la condition préalable a échoué) lorsque le jeton a expiré et qu'il est temps d'appeler le
renew
point de terminaison, qui renverra un code 200 (ok). - Renvoyez 401 pour signaler que la session n'est pas valide ou que le jeton a expiré. Dans ce cas, le client appellera immédiatement le
renew
point de terminaison, s'il renvoie 200, le jeton est actualisé, mais s'ilrenew
renvoie également 401, cela signifie que le client est hors du système.
Laquelle des deux alternatives ci-dessus recommanderiez-vous? Laquelle serait plus standard, plus simple à comprendre et / ou plus RESTful? Ou recommanderiez-vous une approche complètement différente? Voyez-vous des problèmes évidents ou des risques de sécurité avec l'une ou l'autre option? Points supplémentaires si votre réponse comprend des références externes qui soutiennent votre opinion.
MISE À JOUR
Les gars, veuillez vous concentrer sur la vraie question - laquelle des deux alternatives de code http pour signaler un renouvellement / invalidation de session est la meilleure? Cela ne me dérange pas que mon système utilise JWT et des sessions côté serveur, c'est une particularité de mon API pour des règles métier très spécifiques, et non la partie pour laquelle je demande de l'aide;)
la source
Réponses:
Cela ressemble à un cas d' authentification contre autorisation .
Les JWT sont des revendications signées cryptographiquement concernant l'expéditeur d'une demande. Un JWT peut contenir des revendications telles que "Cette demande concerne l'utilisateur X" et "L'utilisateur X a un rôle d'administrateur". L'obtention et la fourniture de cette preuve via des mots de passe, des signatures et TLS est le domaine de l' authentification - prouvant que vous êtes bien ce que vous dites être.
Ce que ces revendications signifient pour votre serveur - ce que les utilisateurs et les rôles spécifiques sont autorisés à faire - est le problème de l' autorisation . La différence entre les deux peut être décrite avec deux scénarios. Supposons que Bob veuille entrer dans la section de stockage restreint de l'entrepôt de son entreprise, mais d'abord, il doit traiter avec un garde nommé Jim.
Scénario A - Authentification
Scénario B - Autorisation
Les délais d'expiration JWT sont un dispositif d'authentification utilisé pour empêcher les autres de les voler. Si tous vos JWT ont des délais d'expiration de cinq minutes, ce n'est pas si grave s'ils sont volés car ils deviendront rapidement inutiles. Cependant, la règle d'expiration de session dont vous parlez ressemble à un problème d'autorisation. Certains changements d'état signifient que l'utilisateur X n'est plus autorisé à faire quelque chose qu'il était capable de faire auparavant. Par exemple, l'utilisateur Bob a peut-être été licencié - peu importe que son badge indique qu'il est Bob, car le simple fait d'être Bob ne lui donne plus aucune autorité au sein de l'entreprise.
Ces deux cas ont des codes de réponse HTTP distincts:
401 Unauthorized
et403 Forbidden
. Le code 401, malheureusement nommé, est destiné aux problèmes d'authentification tels que les informations d'identification manquantes, expirées ou révoquées. 403 est pour l'autorisation, où le serveur sait exactement qui vous êtes mais vous n'êtes tout simplement pas autorisé à faire ce que vous essayez de faire. Dans le cas où le compte d'un utilisateur est supprimé, tenter de faire quelque chose avec un JWT sur un point de terminaison entraînerait une réponse interdite 403. Cependant, si le JWT est expiré, le résultat correct serait 401 non autorisé.Un modèle JWT commun est d'avoir des jetons "longue durée" et "courte durée". Les jetons à longue durée de vie sont stockés sur le client comme des jetons à courte durée de vie, mais ils sont de portée limitée et ne sont utilisés qu'avec votre système d'autorisation pour obtenir des jetons à courte durée de vie. Les tokens à longue durée de vie, comme leur nom l'indique, ont de très longues périodes d'expiration - vous pouvez les utiliser pour demander de nouveaux tokens pendant des jours ou des semaines. Les jetons de courte durée sont les jetons que vous décrivez, utilisés avec des temps d'expiration très courts pour interagir avec votre système. Les jetons de longue durée sont utiles pour implémenter la fonctionnalité Remember Me, vous n'avez donc pas besoin de fournir votre mot de passe toutes les cinq minutes pour obtenir un nouveau jeton de courte durée.
Le problème d '"invalidation de session" que vous décrivez ressemble à une tentative d'invalidation d'un JWT de longue durée, car ceux de courte durée sont rarement stockés côté serveur tandis que ceux de longue durée sont suivis au cas où ils devraient être révoqués. Dans un tel système, la tentative d'acquérir des informations d'identification avec un jeton de longue durée révoqué entraînerait 401 non autorisé, car l'utilisateur pourrait techniquement être en mesure d'acquérir des informations d'identification, mais le jeton qu'il utilise n'est pas adapté à la tâche. Ensuite, lorsque l'utilisateur tente d'acquérir un nouveau jeton de longue durée en utilisant son nom d'utilisateur et son mot de passe, le système peut répondre avec 403 Interdit s'il est expulsé du système.
la source
Votre session API est une chose qui ne devrait pas exister du tout dans un monde RESTful. Les opérations RESTful sont censées être sans état, la session contient un état et n'a donc pas sa place dans un monde RESTful.
Le JWT doit être votre seul moyen de déterminer si un utilisateur est toujours éligible pour accéder à un point de terminaison ou non. Une session ne doit absolument y jouer aucun rôle. Si tel est le cas, vous ne disposez pas d'une API RESTful.
Lorsque vous supprimez complètement la session, ce que si vous visez une API RESTful, vous devez le faire et utiliser uniquement le JWT comme facteur d'authentification, un utilisateur est autorisé à utiliser votre point de terminaison ou non - dans ce cas, le
401 Unauthorized
code de réponse est approprié - et doit appeler lerenew
point de terminaison avecgrant_type=refresh_token
ou quelle que soit l'identification de renouvellement que vous utilisez.Mise à jour:
D'après le commentaire, il semble que le flux de validation du JWT que vous utilisez actuellement ne soit pas correct. La validation est censée ressembler à ceci:
Le serveur,,
RESTful API
doit vérifier la validité du jeton envoyé en tant qu'autorisation. Ce n'est pas la responsabilité duClient
. Il semble que vous ne le fassiez pas actuellement. Implémentez la vérification du JWT de cette façon et vous n'avez pas du tout besoin de sessions.la source
Donc, j'avoue que cela n'a pas beaucoup de sens de m'inquiéter de l'approche la plus RESTful lorsque vous rompez déjà les conventions REST avec la session, mais je comprends que vous répondez aux exigences de votre entreprise.
D'un point de vue REST, le client est authentifié ou non. L'architecture ne se soucie pas beaucoup du pourquoi (c'est-à-dire injecter un état inutile), donc pour répondre à votre question principale, je n'aurais pas du tout de point final renouvelé. Un client connecté enverra toujours son JWT et le serveur le valide toujours et accepte soit en envoyant le code de réussite approprié basé sur l'action 200, 201, etc.) ou rejette avec un 401 ou 403 selon le cas.
Maintenant, le JWT va être associé à un compte quelconque. Ce compte peut être verrouillé ou limité ou autre, et le jeton lui-même peut donc être valide, mais l'action peut être rejetée ailleurs. Si le cas est que le compte d'utilisateur est verrouillé en raison de règles commerciales, il s'agit toujours d'un 401 ou 403 selon la quantité d'informations que vous souhaitez donner au client (différentes entreprises ont des opinions différentes à ce sujet).
Enfin, si vous affirmez que le compte peut être déverrouillé et valide mais que le JWT a juste besoin d'être révoqué, je resterais TOUJOURS avec le 401 ou 403 et conserver quelque chose comme une liste de révocation de certificats de JWT invalides dans laquelle vous pouvez en mettre un , tant qu'il se nettoie lorsque le JWT aurait expiré (la plupart des bases de données ont un moyen de le faire ou vous pouvez avoir des événements dans le code d'application).
la source