decoding JWT token in Golang

Function jwt.ParseWithClaims accept an interface of jwt.Claims as the second argument. Besides struct-based custom claims, the package also provides map-based claims, i.e. jwt.MapClaims. So, you can simply decode the token into a MapClaims, e.g.

tokenString := "<YOUR TOKEN STRING>"    
claims := jwt.MapClaims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
    return []byte("<YOUR VERIFICATION KEY>"), nil
})
// ... error handling

// do something with decoded claims
for key, val := range claims {
    fmt.Printf("Key: %v, value: %v\n", key, val)
}

Disclaimer: I am not affiliated to the library. I'm just a user, find it useful and would like to share.

It's 2019. I would like to suggest an alternate library that does pretty good job on JWT using JWS and/or JWE.

Here is the few examples on how to use the library:

import (
    "gopkg.in/square/go-jose.v2/jwt"
    "gopkg.in/square/go-jose.v2"
)
...

var claims map[string]interface{} // generic map to store parsed token

// decode JWT token without verifying the signature
token, _ := jwt.ParseSigned(tokenString)
_ = token.UnsafeClaimsWithoutVerification(&claims)

// decode JWT token and verify signature using JSON Web Keyset
token, _ := jwt.ParseSigned(tokenString)
jwks := &jose.JSONWebKeySet { // normally you can obtain this from an endpoint exposed by authorization server
            Keys: []jose.JSONWebKey { // just an example
                {
                    Key: publicKey, 
                    Algorithm: jose.RS256, // should be the same as in the JWT token header
                    KeyID: "kid", // should be the same as in the JWT token header
                },
            },
        }
_ = jwt.Claims(jwks, &claims)

Noted that, claims can be a struct that contains default JWT fields and also customized fields that are inside the token E.g.:

import (
    "github.com/mitchellh/mapstructure"
    "gopkg.in/square/go-jose.v2/jwt"
)
...
type CustomClaims struct {
    *jwt.Claims
    // additional claims apart from standard claims
    extra map[string]interface{}
}

func (cc *CustomClaims) UnmarshalJSON(b []byte) error {
    var rawClaims map[string]interface{}
    if err := json.Unmarshal(b, &rawClaims); err != nil {
        return nil
    }
    var claims jwt.Claims
    var decoderResult mapstructure.Metadata
    decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
        Result:   &claims,
        Metadata: &decoderResult,
        TagName:  "json",
    })
    if err != nil {
        return err
    }
    if err := decoder.Decode(rawClaims); err != nil {
        return err
    }
    cc.Claims = &claims
    cc.extra = make(map[string]interface{})
    for _, k := range decoderResult.Unused {
        cc.extra[k] = rawClaims[k]
    }
    return nil
}

I also built a command line tool that uses the library to perform various encoding/decoding activities. It might be a useful reference on the usage of the library too.


Use github.com/dgrijalva/jwt-go go liabary for the implementation. we can extract JWT token information from the api request according to the following way.

When post the JWT token from the using post request. you must extract JWT information in routing section.

  func RequireTokenAuthentication(inner http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            token, err := jwt.ParseFromRequest(
                r,
                func(token *jwt.Token) (interface{}, error) {
                    return VERIFICATION.PublicKey, nil
                })
            if err != nil || !token.Valid) {
                log.Debug("Authentication failed " + err.Error())
                w.WriteHeader(http.StatusForbidden)
                return
            } else {
                r.Header.Set("username", token.Claims["username"].(string))
                r.Header.Set("userid", strconv.FormatFloat((token.Claims["userid"]).(float64), 'f', 0, 64))
            }
            inner.ServeHTTP(w, r)
        })
    }

VERIFICATION.PublicKey : The key for verification(get public key from public.key file in your system)

Any Issue happen.Please let me know. I can give you help.

Tags:

Go

Jwt

Jwt Go