25

I'm using a jwt token for authentication and would like to read the payload information on the client-side. Right now I'm doing something like this:

var payload = JSON.parse(window.atob(token.split('.')[1])); 

Is there a better way to work with jwt tokens within the browser?

Woodsy
  • 3,177
  • 2
  • 26
  • 50
  • 2
    https://github.com/auth0/jwt-decode – robertklep Aug 30 '16 at 13:32
  • Thanks @robertklep I looked at those files earlier but overlooked the .build folder. I posted the solution I used below after following your link. – Woodsy Aug 30 '16 at 14:30
  • Can you explain why you'd want to do this? – CodyBugstein Nov 15 '17 at 20:56
  • Information was being passed in the payload that I needed to read on the front end. I was pretty basic stuff like first name and email address i needed at the time to display in a couple fields. – Woodsy Nov 16 '17 at 01:53

2 Answers2

38

This simple solution returns raw token, header and the payload:

function jwtDecode(t) {
  let token = {};
  token.raw = t;
  token.header = JSON.parse(window.atob(t.split('.')[0]));
  token.payload = JSON.parse(window.atob(t.split('.')[1]));
  return (token)
}
Prcek
  • 413
  • 4
  • 3
  • @AdamReis How to do it only once? – jpenna May 16 '19 at 12:29
  • 4
    Just split the string first, e.g. `const [header, payload] = t.split('.');` then you can convert and JSON parse each part. It's redundant to have to split twice. My earlier comment was not entirely correct. – Adam Reis May 16 '19 at 20:08
  • 1
    You still have to verify the token, otherwise you're just blindly trusting the server. – sean Jan 08 '20 at 06:10
  • 2
    @sean what are you talking about? that's the entire point of JWT, the client doesn't have to verify anything. – r3wt Jun 04 '20 at 13:17
  • You should at least verify the signature portion of the token. Otherwise you could just not use the signature portion at all, at which point why are you using JWTs in the first place? – sean Jun 08 '20 at 09:30
  • 1
    The usefulness of parsing a JWT client side is better UX. – vrtjason Sep 24 '20 at 22:40
  • @sean You can't verify a token client side without revealing the secret that was used to create the signature to the client. If the client has the secret, then it can make any claims it wants to the server. The point is not for the client to trust the server, as you say. It's the other way around. It's so the server can trust the client, i.e., ensure all claims that the client makes are valid. You want the server to give the token to the client. Then the client will use that token for all subsequent requests. The server will verify the token on each request and decide what to do. – Rokit Oct 17 '22 at 22:31
  • 2
    I recommend against using this, because JWT uses base64url instead of base64 (standard). There's a slight difference (- and _) vs (+ and /) between these encodings which will cause some of your inputs to fail. – raimohanska Feb 07 '23 at 10:04
  • @Rokit can't the client still use the jwt via xss? why not use httponly cookie instead of jwt? – Nikos Mar 09 '23 at 16:20
  • 1
    @Nikos I have a meager understanding of that stuff. You might want to check this question: https://stackoverflow.com/questions/60540104/how-worried-should-i-be-about-opening-up-a-jwt-to-an-xss-vulnerability – Rokit Mar 09 '23 at 18:06
35

From https://github.com/auth0/jwt-decode

download .build/jwt-decode.min.js file and include in the project.

<script src="js/jwt-decode.min.js"></script>

var token = 'eyJ0eXAiOo876jgJ96...'; // jwt token;
var decoded = jwt_decode(token);
console.log(decoded);
TGI
  • 559
  • 1
  • 6
  • 15
Woodsy
  • 3,177
  • 2
  • 26
  • 50
  • 2
    I concur! The jwt-decode package is also available on NPM. Unlike the suggestion to use window.atob(), this solution actually works. JWT uses Base64Url encoding which is slightly different from Base64 - this is why window.atob() will fail randomly for parsing JWTs. – raimohanska Feb 09 '23 at 07:50
  • 1
    they should make that lib es6 import friendly, are they living in the 90s – Nikos Mar 09 '23 at 16:17