web-dev-qa-db-fra.com

Comment décoder le jeton jwt en javascript

Comment puis-je décoder la charge utile de JWT en utilisant JavaScript? Sans bibliothèque. Ainsi, le jeton renvoie simplement un objet de charge utile pouvant être utilisé par mon application frontale.

Exemple de jeton: xxxxxxxxx.XXXXXXXX.xxxxxxxx

Et le résultat est la charge utile:

{exp: 10012016 name: john doe, scope:['admin']}
109
Chrisk8er

Est-ce que ça va marcher?

function parseJwt (token) {
            var base64Url = token.split('.')[1];
            var base64 = base64Url.replace('-', '+').replace('_', '/');
            return JSON.parse(window.atob(base64));
        };

Comme mentionné dans les commentaires de Racing Tadpole, remplacer javascript remplace uniquement la première occurrence, utilisez plutôt l'expression régulière:

var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
249
Peheje

Vous pouvez utiliser jwt-decode pour écrire:

import jwt_decode from 'jwt-decode';

var token = 'eyJ0eXAiO.../// jwt token';

var decoded = jwt_decode(token);
console.log(decoded);
/*{exp: 10012016 name: john doe, scope:['admin']}*/
33
Guy

Fonction simple avec try - catch

const parseJwt = (token) => {
  try {
    return JSON.parse(atob(token.split('.')[1]));
  } catch (e) {
    return null;
  }
};

Merci!

15
Rajan Maharjan

@Peheje fonctionnera, mais vous aurez un problème avec unicode . Pour y remédier, j'utilise le code sur https://stackoverflow.com/a/30106551/5277071 ;

let b64DecodeUnicode = str =>
  decodeURIComponent(
    Array.prototype.map.call(atob(str), c =>
      '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    ).join(''))

let parseJwt = token =>
  JSON.parse(
    b64DecodeUnicode(
      token.split('.')[1].replace('-', '+').replace('_', '/')
    )
  )


let form = document.getElementById("form")
form.addEventListener("submit", (e) => {
   form.out.value = JSON.stringify(
      parseJwt(form.jwt.value)
   )
   e.preventDefault();
})
textarea{width:300px; height:60px; display:block}
<form id="form" action="parse">
  <textarea name="jwt">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkrDtGhuIETDs8OoIiwiYWRtaW4iOnRydWV9.469tBeJmYLERjlKi9u6gylb-2NsjHLC_6kZNdtoOGsA</textarea>
  <textarea name="out"></textarea>
  <input type="submit" value="parse" />
</form>

6
Rafael Quintela

J'utilise cette fonction pour obtenir la charge utile, l'en-tête, exp (heure d'expiration), iat (émis à) basé sur this answer

function parseJwt(token) {
  try {
    // Get Token Header
    const base64HeaderUrl = token.split('.')[0];
    const base64Header = base64HeaderUrl.replace('-', '+').replace('_', '/');
    const headerData = JSON.parse(window.atob(base64Header));

    // Get Token payload and date's
    const base64Url = token.split('.')[1];
    const base64 = base64Url.replace('-', '+').replace('_', '/');
    const dataJWT = JSON.parse(window.atob(base64));
    dataJWT.header = headerData;

// TODO: add expiration at check ...


    return dataJWT;
  } catch (err) {
    return false;
  }
}

const jwtDecoded = parseJwt('YOUR_TOKEN') ;
if(jwtDecoded)
{
    console.log(jwtDecoded)
}
4
Softmixt

J'ai trouvé ce code à jwt.io et cela fonctionne bien. 

//this is used to parse base64
function url_base64_decode(str) {
  var output = str.replace(/-/g, '+').replace(/_/g, '/');
  switch (output.length % 4) {
    case 0:
      break;
    case 2:
      output += '==';
      break;
    case 3:
      output += '=';
      break;
    default:
      throw 'Illegal base64url string!';
  }
  var result = window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
  try{
    return decodeURIComponent(escape(result));
  } catch (err) {
    return result;
  }
}

Dans certains cas (certaines plateformes de développement),
la meilleure réponse (pour le moment) fait face à un problème de longueur base64 invalide.
Il me fallait donc un moyen plus stable.

J'espère que cela vous aiderait.

2
Nao Ito

Guy et Peheje ont déjà répondu à la question. Pour un débutant comme moi, il était utile de définir également la ligne d'importation dans l'exemple.

De plus, il m'a fallu quelques minutes pour comprendre que le jeton est l'ensemble complet des informations d'identification qui sont renvoyées (l'ensemble du jeton JWT, pas seulement la partie idToken). Simple une fois que vous le savez ..

import jwt_decode from 'jwt-decode';

var token = 'eyJ0eXAiO.../// jwt token';
var decoded = jwt_decode(token);

/*{exp: 10012016 name: john doe, scope:['admin']}*/

2
Campo Blanco

Comme l'objet "window" n'est pas présent dans l'environnement nodejs, Nous pourrions utiliser les lignes de code suivantes: 

let base64Url = token.split('.')[1]; // token you get
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));

Cela fonctionne parfaitement pour moi. J'espère que ça aide.

1
Avik

Basé sur les réponses ici et ici :

const dashRE = /-/g;
const lodashRE = /_/g;

module.exports = function jwtDecode(tokenStr) {
  const base64Url = tokenStr.split('.')[1];
  if (base64Url === undefined) return null;
  const base64 = base64Url.replace(dashRE, '+').replace(lodashRE, '/');
  const jsonStr = Buffer.from(base64, 'base64').toString();
  return JSON.parse(jsonStr);
};
0
webjay

Solution simple NodeJS pour le décodage d'un jeton Web JSON (JWT)

function decodeTokenComponent(value) {
    const buff = new Buffer(value, 'base64')
    const text = buff.toString('ascii')
    return JSON.parse(text)
}

const token = 'xxxxxxxxx.XXXXXXXX.xxxxxxxx'
const [headerEncoded, payloadEncoded, signature] = token.split('.')
const [header, payload] = [headerEncoded, payloadEncoded].map(decodeTokenComponent)

console.log(`header: ${header}`)
console.log(`payload: ${payload}`)
console.log(`signature: ${signature}`)
0
Derek Soike

toutes les fonctionnalités de jwt.io ne prennent pas en charge toutes les langues. Dans NodeJs, vous pouvez utiliser 

var decoded = jwt.decode(token);
0
Jithin Vijayan