square/js-jose

JWT decoding

rapropos opened this issue · 6 comments

Perhaps this would be considered out of scope for the project, if so, please feel free to ignore. I'm not entirely sure where the best place to add/expose this functionality would be, but given the base64url decoding in Utils, it would be pretty trivial to add a utility function to decode the claims of a JWT. I have a use case where the client receives a JWT signed by a server, and it is expected to return said JWT on successive API requests. The client doesn't necessarily have to verify the signature on the JWT (although there are certainly situations where it would want to). It does need to unpack it and see what's inside, however. I had previously been using auth0/jwt-decode for this, but was thinking that if this functionality was rolled into js-jose, I could drop a dependency.

It should be as simple (error-checking aside) as something like:

decodeJwt(jwt:string):string {
  let parts = jwt.split('.');
  let json = Jose.Utils.Base64Url.decode(parts[1]);
  let rv = JSON.parse(json);
  return rv;
}

I would prefer not to implement jwt in this library. I don't see what's wrong with having a dependency on auth0/jwt-decode and/or just writing you example code (calling into Jose.Utils.Base64Url). I could be wrong, can you explain the pros of supporting JWT?

JWS/JWE/JWT strikes me as a combined ecosystem, and it's nice to have a single, consistent API for dealing with all aspects of it. js-jose has its object hierarchy of signers, verifiers, encrypters, and decrypters. When I'm in the mode of thinking of dealing with it, I have one set of API documentation and source code to keep up-to-date and look at. It feels unnatural to then have to call a function like window.jwt_decode that follows none of the naming or scoping conventions of js-jose (and this would become exacerbated if there is a TypeScript rewrite, as all the js-jose calls will be nicely type-checked and easily imported, with no munging around with globals, making jwt_decode stick out like even more of a sore thumb).

Beginners to the whole JSON encryption standards world (well, me at least) tend to get confused about what the difference between JWE and JWS and JWT are and when they should use which and to what degree they are interchangeable. If they can think to themselves "here is this opaque object I have gotten from somewhere that I want to verify and decrypt" or "here is this thing I want to sign and encrypt and pass it to a server that is expecting a JSON web thingy", and the answer is "go to the js-jose library and make a verifier and a decrypter and give them the object" or "go to the js-jose library and make a signer and a decrypter and give them the secret data", it maps directly to their goal. They don't have to take the intermediate step of thinking "now does this action require a JWE or a JWS or a JWT, and which RFC documents which one of those, and which library do I need to call to handle that?".

ok, would you like to send me a PR? Ideally, it would be nice to have some kind of sub-package/conditional build system. Any suggestions how to get there?

I support this effort, and second rapropos' thinking. It's better for beginners, and in the future, people could just use JS modules to do: import { jwt_decode } from 'js-jose'.

We recently added jwt support to our go library (see square/go-jose@6e3cf7d). Might be helpful to look at for anyone wanting to take a stab at adding support to this library.

Believed addressed by #48.