¿Cómo decodificar un token jwt en javascript sin usar una biblioteca?
¿Cómo puedo decodificar la carga útil de un JWT usando JavaScript? Sin una biblioteca. Para que el token simplemente devuelva un objeto de carga útil que pueda ser consumido por mi aplicación front-end.
Token de ejemplo: xxxxxxxxx.XXXXXXXX.xxxxxxxx
Y el resultado es la carga útil:
{exp: 10012016 name: john doe, scope:['admin']}
Respuesta #1
Nota: esto no valida la firma, solo extrae la carga útil JSON del token, la cual podría haber sido manipulada.
Navegador
Función analizador JWT de texto unicode funcionando:
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 usa base64url (RFC 4648 §5), así que usar solo atob (que usa base64) no es suficiente.
Node.js
function parseJwt (token) {
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}
Respuesta #2
Función simple con try - catch
const parseJwt = (token) => {
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
return null;
}
};
¡Gracias!
Respuesta #3
Puedes usar jwt-decode, así que entonces podrías escribir:
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']}*/
Respuesta #4
usando base64, puedes usar la función pura de JavaScript atob() para decodificar el token en una cadena:
atob(token.split('.')[1]);
o analizarlo directamente en un objeto json:
JSON.parse(atob(token.split('.')[1]));
lee sobre atob() y btoa() funciones integradas de JavaScript para codificación y decodificación Base64 - Web APIs | MDN.
Respuesta #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);
Si estás usando node, es posible que tengas que usar el paquete buffer:
npm install buffer
var Buffer = require('buffer/').Buffer
Respuesta #6
Si estás usando Typescript o JavaScript vanilla, aquí tienes una función simple, lista para copiar y pegar en tu proyecto, sin dependencias (basada en la respuesta de @Rajan Maharjan).
Esta respuesta es particularmente buena, no solo porque no depende de ningún módulo npm, sino también porque no depende de ningún módulo incorporado de node.js (como Buffer) que algunas otras soluciones aquí están usando y que, por supuesto, fallarían en el navegador (a menos que se use un polyfill, pero no hay ninguna razón para hacer eso en primer lugar). Además, JSON.parse puede fallar en tiempo de ejecución y esta versión (especialmente en Typescript) obligará a manejar eso. Las anotaciones de JSDoc harán que los futuros mantenedores de tu código te lo agradezcan. :)
/**
* 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
}
}
Para completar, aquí está también la versión en javascript puro:
/**
* 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
}
}
Respuesta #7
Dado que el objeto "window" no está presente en el entorno de Node.js, podríamos usar las siguientes líneas de código:
let base64Url = token.split('.')[1]; // token you get
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));
Está funcionando perfectamente para mí. Espero que ayude.
Respuesta #8
Si usas Node.JS, puedes usar el módulo nativo Buffer haciendo:
const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6ImU3YjQ0Mjc4LTZlZDYtNDJlZC05MTZmLWFjZDQzNzhkM2U0YSIsImlhdCI6MTU5NTg3NzUxOCwiZXhwIjoxNTk1ODgxMTE4fQ.WXyDlDMMSJAjOFF9oAU9JrRHg2wio-WolWAkAaY3kg4';
const tokenDecodablePart = token.split('.')[1];
const decoded = Buffer.from(tokenDecodablePart, 'base64').toString();
console.log(decoded)
Y ya estás listo para empezar :-)
Respuesta #9
@Peheje funcionará, pero tendrás problemas con unicode. Para solucionarlo uso el código en 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>Respuesta #10
Si estás usando node.js 16 o una versión posterior, puedes usar el codificador/decodificador base64url incorporado.
let payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));
