Cum să decodifici un token JWT în JavaScript fără a folosi o bibliotecă?
Cum pot decoda payload-ul unui JWT folosind JavaScript? Fără o bibliotecă. Deci tokenul să returneze doar un obiect payload care poate fi folosit de aplicația mea front-end.
Exemplu de token: xxxxxxxxx.XXXXXXXX.xxxxxxxx
Și rezultatul este sarcina utilă:
{exp: 10012016 name: john doe, scope:['admin']}
Răspuns #1
Notă: acest lucru nu validează semnătura, ci doar extrage datele JSON din token, care ar fi putut fi modificate.
Browser
Funcție parser JWT pentru text unicode funcțională:
function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
JWT folosește base64url (RFC 4648 §5), deci folosirea doar a atob (care folosește base64) nu este suficientă.
Node.js
function parseJwt (token) {
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}
Răspuns #2
Funcție simplă cu try - catch
const parseJwt = (token) => {
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
return null;
}
};
Mulțumesc!
Răspunsul #3
Poți folosi jwt-decode, astfel încât apoi ai putea scrie:
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']}*/
Răspunsul #4
folosind base64, poți folosi funcția pură JavaScript atob() pentru a decodifica tokenul într-un șir de caractere:
atob(token.split('.')[1]);
sau să îl analizezi direct într-un obiect json:
JSON.parse(atob(token.split('.')[1]));
citește despre funcțiile încorporate JavaScript atob() și btoa() pentru codificarea și decodificarea Base64 - Web APIs | MDN.
Răspunsul #5
function parseJwt(token) {
var base64Payload = token.split('.')[1];
var payload = Buffer.from(base64Payload, 'base64');
return JSON.parse(payload.toString());
}
let payload= parseJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
console.log("payload:- ", payload);
Dacă folosești node, s-ar putea să fie nevoie să folosești pachetul buffer:
npm install buffer
var Buffer = require('buffer/').Buffer
Răspunsul #6
Dacă folosești Typescript sau vanilla JavaScript, iată o funcție simplă, fără dependențe, gata de copiat și inserat în proiectul tău (bazată pe răspunsul lui @Rajan Maharjan).
Acest răspuns este deosebit de bun, nu doar pentru că nu depinde de niciun modul npm, ci și pentru că nu depinde de niciun modul încorporat în node.js (cum ar fi Buffer) pe care unele alte soluții de aici îl folosesc și, desigur, ar eșua în browser (decât dacă este polyfill-uit, dar nu există niciun motiv să faci asta în primul rând). În plus, JSON.parse poate eșua la rulare și această versiune (în special în Typescript) va forța gestionarea acestui lucru. Anotațiile JSDoc îi vor face pe viitorii întreținători ai codului tău să fie recunoscători. :)
/**
* Returns a JS object representation of a Javascript Web Token from its common encoded
* string form.
*
* @template T the expected shape of the parsed token
* @param {string} token a Javascript Web Token in base64 encoded, `.` separated form
* @returns {(T | undefined)} an object-representation of the token
* or undefined if parsing failed
*/
export function getParsedJwt<T extends object = { [k: string]: string | number }>(
token: string,
): T | undefined {
try {
return JSON.parse(atob(token.split('.')[1]))
} catch {
return undefined
}
}
Pentru completare, iată și versiunea în JavaScript simplu:
/**
* Returns a JS object representation of a Javascript Web Token from its common encoded
* string form.
*
* @param {string} token a Javascript Web Token in base64 encoded, `.` separated form
* @returns {(object | undefined)} an object-representation of the token
* or undefined if parsing failed
*/
export function getParsedJwt(token) {
try {
return JSON.parse(atob(token.split('.')[1]))
} catch (error) {
return undefined
}
}
Răspunsul #7
Deoarece obiectul „window” nu este prezent în mediul Node.js, am putea folosi următoarele linii de cod:
let base64Url = token.split('.')[1]; // token you get
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));
Funcționează perfect pentru mine. Sper că ajută.
Răspuns #8
Dacă folosești Node.JS, poți folosi modulul nativ Buffer făcând astfel:
const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6ImU3YjQ0Mjc4LTZlZDYtNDJlZC05MTZmLWFjZDQzNzhkM2U0YSIsImlhdCI6MTU5NTg3NzUxOCwiZXhwIjoxNTk1ODgxMTE4fQ.WXyDlDMMSJAjOFF9oAU9JrRHg2wio-WolWAkAaY3kg4';
const tokenDecodablePart = token.split('.')[1];
const decoded = Buffer.from(tokenDecodablePart, 'base64').toString();
console.log(decoded)
Și ești gata să pleci :-)
Răspunsul #9
@Peheje va funcționa, dar vei avea probleme cu Unicode. Pentru a-l remedia, folosesc codul de la 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>Răspunsul #10
Dacă folosiți node.js 16 sau o versiune ulterioară, puteți folosi codificatorul/decodificatorul base64url încorporat.
let payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));
