Since both the question and answers mention the JWT library github.com/dgrijalva/jwt-go
, please note that this library has been unmaintained for a long time now.
As of June 2021 there is a community fork golang-jwt/jwt, officially blessed by Dave Grijalva, the original author.
This also means that the library import path has changed. Note that the current major version v3
is not on Go modules, therefore you will still see v3.x.x+incompatible
in your go.mod
.
Edit: since August 2021 version v4
of golang-jwt/jwt
is available. This finally supports Go modules. The new version is backward-compatible with previous versions, so in order to migrate simply replace the old import path with:
github.com/golang-jwt/jwt/v4
then update your modules as needed — see also the migration guide for details.
The fork most notably fixes an important security issue with the original library. Before the fix, the library didn't properly handle multiple aud
in the JWT claims, making it actually not compliant with the JWT spec.
Apart from that, the main API is still the same. For example to parse a JWT with HMAC verification:
tokenString := /* raw JWT string*/
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(/* your JWT secret*/), nil
})
if err != nil {
// handle err
}
// validate the essential claims
if !token.Valid {
// handle invalid tokebn
}
To parse a JWT with custom claims, you can define your own struct type and embed jwt.StandardClaims
into it:
type MyClaims struct {
jwt.StandardClaims
MyField string `json:"my_field"`
}
tokenString := /* raw JWT string*/
// pass your custom claims to the parser function
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, errors.New("unexpected signing method")
}
return []byte(/* your JWT secret*/), nil
})
// type-assert `Claims` into a variable of the appropriate type
myClaims := token.Claims.(*MyClaims)
A valid alternative to this library is lestrrat-go/jwx
. The API is slightly different, but also very easy to use:
tokenString := /* raw JWT string*/
// parse and verify signature
tok, err := jwt.Parse(tokenString, jwt.WithVerify(jwa.HS256, []byte(/* your JWT secret */)))
if err != nil {
// handle err
}
// validate the essential claims
if err := jwt.Validate(tok); err != nil {
// handle err
}