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 peux utiliser des 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 le protégerait-il de CSRF?

Mise à jour 1
J'ai vu quelques exemples d'utilisation comme suit:

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

Comment puis-je l'implémenter lorsque je lance une requête sur le serveur depuis le 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 puis je pourrais lire le jeton de l'en-tête.

Mise à jour 2

J'ai installé l'extension Google Chrome Advanced REST Client et j'ai pu passer le jeton comme en-tête personnalisé. Est-il possible de définir ces données d'en-tête via Javascript lorsque vous faites une requête GET au serveur?

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

    Si vous souhaitez les stocker, vous devez utiliser le stockage localStorage ou la session si disponible ou les cookies. Vous devriez également utiliser l'en-tête de l'autorisation, mais au lieu du schéma de base, utilisez le support:

     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> 

    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'inclue pas automatiquement le contenu du stockage Web dans les requêtes HTTP, ce qui ne le rend pas vulnérable au CSRF
    • Peut être accessible par Javascript en cours d'exécution dans le même domaine qui a créé les données
    • Permet d'utiliser l'approche la plus sémantiquement correcte pour passer les authentifications d'authentification token en HTTP (l'en-tête d' Authorization avec un système de Bearer )
    • Il est très facile de choisir les demandes qui devraient contenir une authentification

    Les inconvénients

    • Ne peut pas être consulté par Javascript en cours d'exécution 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 demandes authentifiées, vous ne pouvez utiliser que les API de navigateur / bibliothèque qui vous permettent de personnaliser la demande (passez le jeton dans l'en-tête de l' Authorization )

    Usage

    Vous exploitez le navigateur localStorage ou sessionStorage API pour stocker, puis récupérez le jeton lors de l'exécution des requêtes.

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

    Option 2 – Cookie HTTP uniquement

    Avantages

    • Ce n'est pas vulnérable à XSS
    • Le navigateur inclut automatiquement le jeton dans toute requête répondant aux spécifications des cookies (domaine, chemin d'accès et durée de vie)
    • Le cookie peut être créé dans un domaine de niveau supérieur et utilisé dans les requêtes effectuées par des sous-domaines

    Les inconvénients

    • ⚠️ Il est vulnérable à CSRF
    • Vous devez être conscient et toujours considérer l'utilisation possible des cookies dans les sous-domaines
    • Cherry choisissant les demandes qui devraient inclure le cookie est faisable mais plus désordonné
    • Vous pouvez (encore) frapper certains problèmes avec de petites différences dans la façon dont les navigateurs traitent les cookies
    • ⚠️ Si vous n'êtes pas prudent, vous pouvez mettre en œuvre une stratégie d'atténuation CSRF vulnérable à XSS
    • Le côté serveur doit valider un cookie pour l'authentification au lieu de l'en-tête d' Authorization plus approprié

    Usage

    Vous n'avez besoin de rien faire du côté du client car le navigateur prend automatiquement soin de vos affaires.

    Option 3 – cookie accessible par Javascript ignoré par le serveur

    Avantages

    • Ce n'est pas vulnérable au CSRF ( car il est ignoré par le serveur )
    • Le cookie peut être créé dans un domaine de niveau supérieur et utilisé dans les requêtes effectuées par des sous-domaines
    • Permet d'utiliser l'approche la plus sémantiquement correcte pour passer les authentifications d'authentification token en HTTP (l'en-tête d' Authorization avec un système de Bearer )
    • Il est assez facile de choisir les demandes qui devraient contenir une authentification

    Les inconvénients

    • ⚠️ C'est vulnérable à XSS
    • Si vous ne faites pas attention au chemin où vous avez configuré le cookie, le cookie est automatiquement inclus dans le navigateur dans les demandes qui ajouteront des frais généraux inutiles
    • Pour effectuer des demandes authentifiées, vous ne pouvez utiliser que les API de navigateur / bibliothèque qui vous permettent de personnaliser la demande (passez le jeton dans l'en-tête de l' Authorization )

    Usage

    Vous exploitez l'API document.cookie du navigateur pour stocker, puis récupérer le jeton lors de l'exécution des requêtes. Cette API n'est pas aussi fine que le stockage Web (vous obtenez tous les cookies) afin que vous ayez 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 

    Notes complémentaires

    Cela peut sembler une option bizarre, mais il a le bénéfice agréable que vous pouvez avoir le stockage à la disposition d'un domaine de premier niveau et de tous les sous-domaines, ce qui est quelque chose que le stockage Web ne vous donnera pas. Cependant, il est plus complexe à mettre en œuvre.


    Conclusion – Notes finales

    Ma recommandation pour les scénarios les plus communs serait d'aller avec l'option 1 , surtout parce que:

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

    Notez également que les options basées sur les cookies sont également très différentes, car les cookies de l'option 3 sont utilisés uniquement comme un mécanisme de stockage, de sorte que ce soit presque comme un détail de mise en œuvre du client. Cependant, l'option 2 signifie une manière plus traditionnelle de traiter l'authentification; Pour une lecture supplémentaire sur ces 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 signifie que des cookies devraient être créés de manière appropriée pour tenir compte de cela.

    Ce blog affiche une excellente comparaison côte-à-côte du stockage du navigateur par rapport aux cookies et aborde chaque attaque potentielle 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 ajoutez un jeton xsrf dans le jwt. Une explication détaillée dans la publication du blog.