Working with JWT in Go
github.com/lestrrat-go/jwx (JWX) is a complete package that covers the entirety of Javascript Object Signing and Encryption (JOSE) for Go. It is (for unknown reasons) often used when JWK handling is required. But yes, it does handle JWTs, and if you are using JWX for JWKs, you should also use it for JWTs.
Let me show you a few simple steps to sign and verify JWTs using JWX
TL;DR:
- If you are using github.com/lestrrat-go/jwx/v2/jwk somewhere in your code, you might as well use github.com/lestrrat-go/jwx/v2/jwt to handle your JWTs
- It will be one less dependency, and everything works seamlessly out of the box. No extra external packages required just to load a JWK!
- All examples below can be found in the
examples
directory for JWX. And there are a lot of documentation both in the repository itself, and thego doc
Parsing a JWK or JWKS
First, you will need to obtain a JWK to sign or verify a token.
Using JWX, you can parse either a single JWK or a JWK Set (JWKS).
- Parse from a JSON
[]byte
sequence, or - Parse from a file containing the key.
And you could even do the above if the above two are represented as PEM-encoded ASN.1 DER format.
Here’s how to parse a JWK JSON []byte
sequence containing a single key:
Here’s how to parse a file containing JWKS in JSON[]byte
sequence.
And finally, here’s how to read from a file containing JWKS in PEM-encoded ASN.1 DER format. Notice the optional parameter jwk.WithPEM(true)
. You can pass this into jwk.ParseKey
or jwk.Parse
and achieve the same effect
There are other tricks to get JWK/JWKS using JWX, such as creating a JWK directly from the “raw” key, or minimize fetching using the jwk.Cache
(but also keep the keys up-to-date). Please read the documentation (1, 2) for more details.
Building JWTs
Building JWTs using JWX is simple and intuitive. Just use jwt.Builder
, and you’re set. Notice that you don’t need to create your custom struct
to include private claims. Using JWX, tokens with arbitrary private parameters are supported out of the box.
Accessing JWT claims
Claims stored in JWTs can be accessed via either the predefined accessors or the generic .Get()
method. Since JWTs in JWX can handle any private claims, you can use the same API to access any of the fields.
The example also contains an example to convert specific fields into a custom type.
Signing JWTs
Now that you have JWT and a JWK, you can sign JWTs. jwt.Sign()
, that’s it! Note that you can use either the raw key or the key generated by calling jwt.FromRaw
. JWX Does The Right Thing with the provided keys.
Verifying JWTs
The one thing that I pride myself in the JWX library is the symmetric API design. If you were able to sign JWTs, then it should be easy to learn how to verify it.
Below example shows how to verify a JWT… actually, verification is part of the parsing process, and will be performed unless you explicitly disable it. So in the spirit of symmetry, all you need to do is to use jwt.Parse
with the jwt.WithKey
option to verify it.
Note that in this example we are also setting jwt.WithValidate(false)
to bypass JWT validation for demonstration purposes.
It’s simple, it’s built-in, and it’s straight forward.
Please use the built-in JWT package if you are already using github.com/lestrrat-go/jwx for your JWK needs!