Où enregistrer un JWT dans une application basée sur un navigateur et comment l'utiliser

J'essaie d'implémenter JWT dans mon système d'authentification et j'ai quelques questions. Pour stocker le jeton, je pourrais utiliser les cookies, mais il est également possible d'utiliser localStorage ou sessionStorage.

Quel serait le meilleur choix?

J'ai lu que JWT protège le site de CSRF. Cependant, je ne peux pas imaginer comment cela fonctionnerait en supposant que je sauvegarde le jeton JWT dans le stockage des cookies.

Comment protégerait-il alors de CSRF?

Mise à Jour 1
J'ai vu quelques exemples d'utilisation comme le suivant:

curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"

Comment puis-je implémenter cela lorsque je fais une demande au serveur à partir du navigateur? J'ai également vu que certains implémentent le jeton dans L'URL:

http://exmple.com?jwt=token

Si je faisais une demande via AJAX, je pourrais définir un en-tête comme jwt: [token] et ensuite je pourrais lire le jeton de l'en-tête.

Mise à Jour 2

J'ai installé L'extension Google Chrome du client REST avancé et j'ai pu passer le jeton en tant qu'en-tête personnalisé. Est-il possible de définir ces données d'en-tête via Javascript lors d'une requête GET sur le serveur?

37
demandé sur João Angelo 2014-10-13 16:41:49

3 réponses

Oeil à ce site web: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

Si vous souhaitez les stocker, vous devez utiliser localStorage ou sessionStorage si disponible ou cookies. Vous devez également utiliser L'en-tête Authorization, mais au lieu du schéma de base, utilisez celui du porteur:

curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"

Avec JS, vous pouvez utiliser le code suivant:

<script type='text/javascript'>
// define vars
var url = 'https://...';

// ajax call
$.ajax({
    url: url,
    dataType : 'jsonp',
    beforeSend : function(xhr) {
      // set header if JWT is set
      if ($window.sessionStorage.token) {
          xhr.setRequestHeader("Authorization", "Bearer " +  $window.sessionStorage.token);
      }

    },
    error : function() {
      // error handler
    },
    success: function(data) {
        // success handler
    }
});
</script>
20
répondu Florent Morselli 2017-05-27 00:07:05

Choisir le stockage est plus sur les compromis que d'essayer de trouver un meilleur choix définitif. Passons par quelques options:

Option 1 - Stockage Web (localStorage ou sessionStorage)

Avantages

  • le navigateur n'inclura automatiquement rien du stockage Web dans les requêtes HTTP, ce qui le rend Non vulnérable à CSRF
  • N'est accessible que par Javascript s'exécutant dans le même domaine que celui qui a créé les données
  • permet d'utiliser le plus approche sémantiquement correcte pour passer les informations D'identification d'authentification de jeton dans HTTP (l'en-tête Authorization avec un schéma Bearer)
  • Il est très facile de sélectionner les requêtes qui doivent contenir l'authentification

Contre

  • ne peut pas être accessible par Javascript s'exécutant dans un sous-domaine de celui qui a créé les données (une valeur écrite par example.com ne peut pas être lue par sub.example.com)
  • ⚠ ️ est vulnérable à XSS
  • pour effectuer des requêtes authentifiées, vous ne pouvez utilisez les API du navigateur/bibliothèque qui vous permettent de personnaliser la requête (passez le jeton dans l'en-tête Authorization)

Utilisation

Vous tirez parti du navigateur localStorage ou sessionStorage API pour stocker puis récupérer le jeton lors de l'exécution des demandes.

localStorage.setItem('token', 'asY-x34SfYPk'); // write
console.log(localStorage.getItem('token')); // read

Option 2-cookie HTTP uniquement

Avantages

  • C'est Pas vulnérable à XSS
  • le navigateur inclut automatiquement le jeton dans toute requête qui répond au cookie spécification (domaine, chemin et durée de vie)
  • le cookie peut être créé dans un domaine de premier niveau et utilisé dans des requêtes effectuées par des sous-domaines

Contre

  • ⚠ ️ Il est vulnérable à CSRF
  • vous devez être conscient et toujours considérer l'utilisation possible des cookies dans les sous-domaines
  • cerise choisir les requêtes qui devraient inclure le cookie est faisable mais messier
  • Vous pouvez (encore) rencontrer quelques problèmes avec de petites différences dans la façon dont les navigateurs traiter les cookies
  • ⚠ ️ si vous ne faites pas attention, vous pouvez mettre en œuvre une stratégie d'atténuation CSRF qui est vulnérable à XSS
  • le côté serveur doit valider un cookie pour l'authentification au lieu de l'en-tête Authorization plus approprié

Utilisation

Vous n'avez pas besoin de faire quoi que ce soit côté client car le navigateur s'occupera automatiquement des choses pour vous.

Option 3-cookie Javascript accessible ignoré par côté serveur

Avantages

  • C'est pas vulnérables à CSRF (parce qu'il est ignoré par le serveur)
  • le cookie peut être créé dans un domaine de premier niveau et utilisé dans des requêtes effectuées par des sous-domaines
  • permet d'utiliser l'approche la plus sémantiquement correcte pour passer des informations D'authentification de jeton dans HTTP (l'en-tête Authorization avec un schéma Bearer)
  • Il est un peu facile de choisir les requêtes qui devraient contenir authentification

Contre

  • ⚠ ️ Il est vulnérable à XSS
  • Si vous ne faites pas attention au chemin où vous définissez le cookie, le cookie est automatiquement inclus par le navigateur dans les requêtes, ce qui ajoutera des frais généraux inutiles
  • pour effectuer des requêtes authentifiées, vous ne pouvez utiliser que les API du navigateur / bibliothèque qui vous permettent de personnaliser la requête (passez le jeton dans l'en-tête Authorization)

Utilisation

Vous tirez parti de la navigateur document.cookie API pour stocker puis récupérer le jeton lors de l'exécution des demandes. Cette API n'est pas aussi fine que le stockage Web (vous obtenez tous les cookies), vous avez donc besoin d'un travail supplémentaire pour analyser les informations dont vous avez besoin.

document.cookie = "token=asY-x34SfYPk"; // write
console.log(document.cookie); // read

Remarques Supplémentaires

Cela peut sembler une option étrange, mais cela a le bel avantage que vous pouvez avoir du stockage disponible pour un domaine de premier niveau et tous les sous-domaines qui sont quelque chose que le stockage Web ne vous donnera pas. Cependant, il est plus complexe d' mettre.


Conclusion-Notes Finales

Mon recommandation pour les scénarios les plus courants, serait d'aller avec l'Option 1, principalement parce que:

  • Si vous créez une application Web, vous devez gérer XSS; toujours, indépendamment de l'endroit où vous stockez vos jetons
  • Si vous n'utilisez pas L'authentification basée sur les cookies, CSRF ne devrait même pas apparaître sur votre radar, donc c'est une chose de moins à craindre

Notez également que le cookie basé sur les options sont également très différentes, car les cookies de L'Option 3 sont utilisés uniquement comme un mécanisme de stockage, donc c'est presque comme si c'était un détail d'implémentation du côté client. Cependant, L'Option 2 signifie une façon plus traditionnelle de traiter l'authentification; pour une lecture plus approfondie de cette chose cookies vs token, vous pouvez trouver cet article intéressant: Cookies vs Tokens: the Definitive Guide .

Enfin, aucune des options ne le mentionne, mais L'utilisation de HTTPS est obligatoire bien sûr, ce qui les cookies moyens devraient être créés de manière appropriée pour prendre cela en considération.

63
répondu João Angelo 2016-11-02 10:42:53

Cet article de blog a une excellente comparaison côte à côte du stockage du navigateur par rapport aux cookies et s'attaque à toutes les attaques potentielles dans chaque cas. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

La réponse / spoiler plus courte: cookies et Ajouter un jeton xsrf dans le jwt. Explication détaillée dans le billet de blog.

8
répondu Carlos Arrastia 2015-07-19 07:26:07