529

How can I decode the payload of JWT using JavaScript? Without a library. So the token just returns a payload object that can consumed by my front-end app.

Example token: xxxxxxxxx.XXXXXXXX.xxxxxxxx

And the result is the payload:

{exp: 10012016 name: john doe, scope:['admin']}
Ojasvi Monga
  • 4,437
  • 2
  • 18
  • 35
Chrisk8er
  • 5,660
  • 3
  • 14
  • 15
  • 2
    How was it encoded? Just do the reverse. You will need the shared secret. – Lucky Soni Jul 24 '16 at 12:35
  • It was encoded by backend api that used php library. In here i need is the payload that encoded using base64 i guess... – Chrisk8er Jul 24 '16 at 12:44
  • 1
    You could try going to the https://jwt.io/ website and getting the JavaScript library it provides. – Quentin Jul 24 '16 at 12:59
  • 67
    Since this question has some traffic, I want to add a disclaimer: If you blindly decode the payload of the token, without validating the signature, you may (or may not) run into security issues! Make sure you understand your security architecture, before blindly using any code provided in this stackoverflow question. – Carsten Hoffmann Jan 22 '18 at 16:55
  • 8
    @CarstenHoffmann And how exactly do I validate the signature ?? – Saurabh Tiwari Sep 28 '18 at 09:25
  • 4
    @SaurabhTiwari Generally you as a client CAN'T validate the signature. See here [stackoverflow.com/questions/59632301/](https://stackoverflow.com/questions/59632301/does-jwt-rs256-requires-openssl-cant-decode-jwt-in-php/59771281#59771281) for clarifications of what a JWT is, the difference between signature and encoding and how is intended to be used. – Diego Mazzaro Jan 18 '20 at 14:14
  • Hereby I'm just going to second Crasten Hoffman's comment. @CarstenHoffmann I recommend adding it as an answer because it's so important and already has 40 upvotes which is enough support for being an answer. – aderchox Apr 14 '22 at 11:54
  • The question isn't "How?", but rather "should you?", I mean for a better level of security just keep the token stored in httpOnly cookie to be validated by the server only, while you send the informations that you need about your user (name, roles etc..) in the response body itself without encryption. – Yassir Khaldi Apr 24 '23 at 16:46

23 Answers23

1110

Note: this does not validate the signature, it just extracts the JSON payload from the token, which could have been tampered with.

Browser

Working unicode text JWT parser function:

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 uses base64url (RFC 4648 §5), so using only atob (which uses base64) isn't enough.

Node.js

function parseJwt (token) {
    return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}
Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
Peheje
  • 12,542
  • 1
  • 21
  • 30
  • 9
    This solution can even be used in Postman (tests tap) cause it does not require any addition library installation. I used it to extract userid from the auth-token. – Wlad Oct 05 '17 at 21:32
  • 9
    NOTE: In Postman I had to remove "window" from `JSON.parse(window.atob(base64))` to make it work. Just `return JSON.parse(atob(base64));` and then `postman.setEnvironmentVariable("userId", parseJwt(jsonData.access_token));` "access_token" is in my case the key of token's value in response (may differ in your case). – Wlad Oct 05 '17 at 21:37
  • 11
    It's better to use `jwt-decode` module because it's small but does a bit more better handling. – Rantiev Feb 13 '18 at 11:13
  • to get the header data also https://stackoverflow.com/a/50819510/1596471 – Softmixt Jun 12 '18 at 14:28
  • 7
    Perhaps trivial to some, but don't forget to add atob as a dependency by adding const atob = require('atob'); – Francis May 28 '20 at 06:16
  • 19
    If you are using NodeJS, and have no access to atob, use this instead: `Buffer.from(base64, 'base64').toString()` – Wilhelm Sorban Jul 24 '20 at 19:06
  • why will this work properly with `utf-8` atob can't decode utf8 correctly? is that what the `replace` fixes? – david_adler Nov 03 '20 at 18:46
  • 2
    is it a good idea to parse the token in frontend? – Sapna Dhalor Jun 10 '21 at 11:38
  • 1
    @peheje Why is there a need to replace "-" with "+" and "_" with "/" ? – rohitwtbs Jul 15 '21 at 09:44
  • 1
    The function atob is deprecated, use `Buffer.from(base64, 'base64').toString()` instead – kigawas Sep 02 '21 at 09:11
  • 3
    `Why is there a need to replace "-" with "+" and "_" with "/"?` because you need to convert [base64url](https://base64.guru/standards/base64url) encoding to the usual base64 first. – Alexander Farber Oct 12 '21 at 10:40
  • 1
    @kigiwas `atob` is only deprecated on Node.js, not in the browser. Use `window.atob` if VSCode complains. – mb21 Jun 16 '22 at 14:03
  • @Rantiev let us know if you find anything this doesn't handle and the jwt-decode lib does, I just [asked over there as well](https://github.com/auth0/jwt-decode/issues/131). – mb21 Jun 16 '22 at 14:09
  • here's the one liner: `(token) => JSON.parse(decodeURIComponent(window.atob(token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/')).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join('')))` – David Kamer Oct 09 '22 at 17:49
168

Simple function with try - catch

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

Thanks!

Rajan Maharjan
  • 4,398
  • 2
  • 16
  • 26
  • 5
    `atob` has known [unicode problems](https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem) – Tamer Shlash Jan 10 '20 at 14:28
  • 23
    [JWT uses base64url](https://tools.ietf.org/html/rfc7519#section-3) ([RFC 4648 §5](https://tools.ietf.org/html/rfc4648#section-5)). This answer uses base64. This answer is wrong. – Pang Sep 09 '20 at 00:14
  • @Pang The algorithm used by atob() and btoa() is specified in RFC 4648. link: https://developer.mozilla.org/en-US/docs/Glossary/Base64 – Rajan Maharjan Sep 09 '20 at 17:22
  • @RajanMaharjan The [MDN page](https://developer.mozilla.org/en-US/docs/Glossary/Base64) says: *"The algorithm used by atob() and btoa() is specified in [RFC 4648, section 4](https://tools.ietf.org/html/rfc4648#section-4)"*, but [JWT](https://tools.ietf.org/html/rfc7519#section-3)([JWS](https://tools.ietf.org/html/rfc7515#section-3)) uses base64url which is defined in [RFC 4648, Section 5](https://tools.ietf.org/html/rfc4648#section-5). The encoding are different. See also [Base64 - Variants summary table](https://en.wikipedia.org/wiki/Base64#Variants_summary_table) on wikipedia. – Pang Sep 10 '20 at 00:04
  • tried with firebase token, it doesn't work – Huy - Logarit Aug 23 '21 at 02:59
  • 1
    jep, doesn't work if you have special characters in the token.. – mb21 Jun 16 '22 at 13:01
60

You can use jwt-decode, so then you could write:

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']}*/
Guy
  • 10,931
  • 5
  • 36
  • 47
48

you can use pure javascript atob() function to decode token into a string:

atob(token.split('.')[1]);

or parse directly it into a json object:

JSON.parse(atob(token.split('.')[1]));

read about atob() and btoa() built-in javascript functions Base64 encoding and decoding - Web APIs | MDN.

Muhammed Moussa
  • 4,589
  • 33
  • 27
  • 16
    [JWT uses base64url](https://tools.ietf.org/html/rfc7519#section-3) ([RFC 4648 §5](https://tools.ietf.org/html/rfc4648#section-5)). This answer uses base64. This answer is wrong. – Pang Sep 09 '20 at 00:16
35
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);

If using node, you might have to use buffer package:

npm install buffer
var Buffer = require('buffer/').Buffer
Adam
  • 3,415
  • 4
  • 30
  • 49
hashinclude72
  • 847
  • 8
  • 10
  • 4
    I use this instead of `atob` because it's deprecated. – Amir Savand Oct 12 '21 at 22:42
  • 4
    This is a good answer for Node.js. But in browsers, `Buffer` doesn't exists (your framework may add a big polyfill), while `atob` is only deprecated on Node.js and perfectly fine to use in the browser. – mb21 Jun 16 '22 at 14:13
20

As "window" object is not present in nodejs environment, we could use the following lines of code :

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

It's working for me perfectly. Hope it helps.

Avik
  • 739
  • 9
  • 15
  • why do you do `.toString('binary')`? that messes things up for me if there are special characters in the token... using `.toString()` works though... – mb21 Jun 16 '22 at 13:03
20

If you're using Typescript or vanilla JavaScript, here's a zero-dependency, ready to copy-paste in your project simple function (building on @Rajan Maharjan 's answer).

This answer is particularly good, not only because it does not depend on any npm module, but also because it does not depend an any node.js built-in module (like Buffer) that some other solutions here are using and of course would fail in the browser (unless polyfilled, but there's no reason to do that in the first place). Additionally JSON.parse can fail at runtime and this version (especially in Typescript) will force handling of that. The JSDoc annotations will make future maintainers of your code thankful. :)

/**
 * 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
  }
}

For completion, here's the vanilla javascript version too:

/**
 * 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
  }
}
maninak
  • 2,633
  • 2
  • 18
  • 33
  • 1. This does not encode all parts of the JWT, but only one: "Payload" is decoded while "Header" and "Signature" are discarded. That is worth noting in the documentation. 2. The return type is too restrictive, because it only allows strings and numbers as values, but the example in RFC 7519, Section 3.1. uses a boolean value, illustrating the problem. 3. Your implementation does not check that the signature of the JWT matches its payload. This *can* be problematic, depending on how your function is used. This should be mentioned in the documentation because it poses a security risk. – Lorenz Leutgeb Feb 18 '21 at 11:01
  • 2
    @LorenzLeutgeb all valid comments I would expect to see in a github issue for a library published on NPM aimed at tackling the JWT decoding/parsing problem. Given that people on this Stack Overflow question are most probably looking for copy-pasta **script** instead of a library, I did my best to balance improving upon all other answers I saw here and at the same time keep the code readable and expandable/maintainable. Cheers and thank you taking the time to clarify those things. – maninak Feb 18 '21 at 16:05
  • Failed for me with UTF-8 characters in JWT claims. – norekhov Apr 15 '22 at 21:28
  • This solution is, however, not zero dependency. It utilizes `atob` which is not part of Javascript but is a Web API. Support is fairly good, browsers support it. Node supports it since v16 (which means that currently there are hosts running Node 14, e.g. AWS Lambda, which doesn't support it). – Emil Oberg May 05 '22 at 19:30
14

If you use Node.JS, You can use the native Buffer module by doing :

const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6ImU3YjQ0Mjc4LTZlZDYtNDJlZC05MTZmLWFjZDQzNzhkM2U0YSIsImlhdCI6MTU5NTg3NzUxOCwiZXhwIjoxNTk1ODgxMTE4fQ.WXyDlDMMSJAjOFF9oAU9JrRHg2wio-WolWAkAaY3kg4';
const tokenDecodablePart = token.split('.')[1];
const decoded = Buffer.from(tokenDecodablePart, 'base64').toString();
console.log(decoded)

And you're good to go :-)

mesqueeb
  • 5,277
  • 5
  • 44
  • 77
Chalom.E
  • 617
  • 5
  • 20
13

@Peheje will work, but you will have problem with unicode. To fix it I use the code on 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>
Rafael Quintela
  • 1,908
  • 2
  • 12
  • 14
  • 1
    +1 but if Racing Tadpole's comment on Peheje's answer is correct (that the replace calls will only replace the first instance), then the same fix would apply here. – Gary McGill Feb 28 '20 at 09:45
10

If using node.js 16 or later, you can use the built-in base64url encoder/decoder.

let payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));
Vasyl Boroviak
  • 5,959
  • 5
  • 51
  • 70
8

I use this function to get payload , header , exp(Expiration Time), iat (Issued At) based on 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)
}
Softmixt
  • 1,658
  • 20
  • 20
  • This answer is somewhat better, but it has two and a half issues. First, it doesn't check the signature (array item 2). Second, the REPLACEs won't work correctly, because they miss the "g" flag on the regex (will only replace the first occurrences of - and _ on the JWT, like Racing Tadpole commented on another post). And the half: to decode array items 0 and 1, you could have used a FOR loop, instead of duplicating the whole code (it's a short code, but could be made more efficient, as the way it is, the SPLIT is executed twice). – Cyberknight Apr 05 '20 at 01:02
7

I found this code at jwt.io and it works well.

//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;
  }
}

In some cases(certain development platforms),
the best answer(for now) faces a problem of invalid base64 length.
So, I needed a more stable way.

I hope it would help you.

Nao Ito
  • 79
  • 1
  • 5
5

Answer based from GitHub - auth0/jwt-decode. Altered the input/output to include string splitting and return object { header, payload, signature } so you can just pass the whole token.

var jwtDecode = function (jwt) {

        function b64DecodeUnicode(str) {
            return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) {
                var code = p.charCodeAt(0).toString(16).toUpperCase();
                if (code.length < 2) {
                    code = '0' + code;
                }
                return '%' + code;
            }));
        }

        function 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!";
            }

            try {
                return b64DecodeUnicode(output);
            } catch (err) {
                return atob(output);
            }
        }

        var jwtArray = jwt.split('.');

        return {
            header: decode(jwtArray[0]),
            payload: decode(jwtArray[1]),
            signature: decode(jwtArray[2])
        };

    };
calingasan
  • 805
  • 10
  • 7
5

You can define & use this one liner func:

jwtDecode = b => JSON.parse(Buffer.from(b.split('.')[1], 'base64').toString('binary'));
drordk
  • 388
  • 3
  • 9
4

all features of jwt.io doesn't support all languages. In NodeJs you can use

var decoded = jwt.decode(token);
Jithin Vijayan
  • 307
  • 5
  • 19
  • 1
    Without library you just perform base64 decoding in second part of token { var payload = token.split('.')[1]); } Then perform base64 decoding { var decodedData = atob(payload); } – Jithin Vijayan Sep 20 '17 at 08:45
2

Simple NodeJS Solution for Decoding a JSON Web Token (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}`)
Derek Soike
  • 11,238
  • 3
  • 79
  • 74
2

In Node.js (TypeScript):

import { TextDecoder } from 'util';

function decode(jwt: string) {
    const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split('.');

    if (length !== 3) {
        throw new TypeError('Invalid JWT');
    }

    const decode = (input: string): JSON => { return JSON.parse(new TextDecoder().decode(new Uint8Array(Buffer.from(input, 'base64')))); };

    return { header: decode(encodedHeader), payload: decode(encodedPayload), signature: signature };
}

With jose by panva on GitHub, you could use the minimal import { decode as base64Decode } from 'jose/util/base64url' and replace new Uint8Array(Buffer.from(input, 'base64')) with base64Decode(input). Code should then work in both browser and Node.js.

2

Plain Javascript Solution:

function decodeJWT(token) {
  const parts = token.split('.');
  if (parts.length !== 3) {
    throw new Error('Invalid token format');
  }
  const header = JSON.parse(atob(parts[0]));
  const payload = JSON.parse(atob(parts[1]));
  return { header, payload };
}

and then you just use it like this:

const token = CREDENTIAL_YOU_GET_FROM_GOOGLE_LOGIN;
const decoded = decodeJWT(token);
console.log(decoded.header); // { "alg": "HS256", "typ": "JWT" }
console.log(decoded.payload); // { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }

This worked fine for my solution. Of course you apply validation before you do anything with the credentials.

basZero
  • 4,129
  • 9
  • 51
  • 89
1

Here is a more feature-rich solution I just made after studying this question:

const parseJwt = (token) => {
    try {
        if (!token) {
            throw new Error('parseJwt# Token is required.');
        }

        const base64Payload = token.split('.')[1];
        let payload = new Uint8Array();

        try {
            payload = Buffer.from(base64Payload, 'base64');
        } catch (err) {
            throw new Error(`parseJwt# Malformed token: ${err}`);
        }

        return {
            decodedToken: JSON.parse(payload),
        };
    } catch (err) {
        console.log(`Bonus logging: ${err}`);

        return {
            error: 'Unable to decode token.',
        };
    }
};

Here's some usage samples:

const unhappy_path1 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvtmalformedtoken');
console.log('unhappy_path1', unhappy_path1);

const unhappy_path2 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvt.malformedtoken');
console.log('unhappy_path2', unhappy_path2);

const unhappy_path3 = parseJwt();
console.log('unhappy_path3', unhappy_path3);

const { error, decodedToken } = parseJwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
if (!decodedToken.exp) {
    console.log('almost_happy_path: token has illegal claims (missing expires_at timestamp)', decodedToken);
    // note: exp, iat, iss, jti, nbf, prv, sub
}

I wasn't able to make that runnable in StackOverflow code snippet tool, but here's approximately what you would see if you ran that code:

enter image description here

I made the parseJwt function always return an object (to some degree for static-typing reasons).

This allows you to utilize syntax such as:

const { decodedToken, error } = parseJwt(token);

Then you can test at run-time for specific types of errors and avoid any naming collision.

If anyone can think of any low effort, high value changes to this code, feel free to edit my answer for the benefit of next(person).

agm1984
  • 15,500
  • 6
  • 89
  • 113
0

Based on answers here and here:

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);
};
webjay
  • 5,358
  • 9
  • 45
  • 62
0

in node.js

JSON.parse(
      Buffer.from(token.split(".")[1], "base64").toString("utf-8")
    )
Suhas C V
  • 104
  • 1
  • 5
0
try {
  const jwt = "JWT-TOKEN";
  const tokenData = JSON.parse(atob(jwt.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
  console.log(tokenData);
} catch (error) {
  console.error("Error decoding JWT:", error);
}
Vinodh Ram
  • 709
  • 1
  • 9
  • 22
-2

An es-module friendly simplified version of jwt-decode.js

function b64DecodeUnicode(str) {
  return decodeURIComponent(
    atob(str).replace(/(.)/g, function (m, p) {
      var code = p.charCodeAt(0).toString(16).toUpperCase();
      if (code.length < 2) {
        code = "0" + code;
      }
      return "%" + code;
    })
  );
}

function base64_url_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!";
  }

  try {
    return b64DecodeUnicode(output);
  } catch (err) {
    return atob(output);
  }
}

export function jwtDecode(token, options) {
  options = options || {};
  var pos = options.header === true ? 0 : 1;
  try {
    return JSON.parse(base64_url_decode(token.split(".")[pos]));
  } catch (e) {
    console.log(e.message);
  }
}
Morgan
  • 1