Pretty Printing JSON Web Tokens (JWTs) on the Command Line using Go

Featured image for sharing metadata for article

Similar to my previous articles in this series, you may want to create a command-line Go app to decode JWTs.

Let us use the following JWT in example.jwt, via JWT.io:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

As well as the following encrypted JWT (JWE) from RFC7516: JSON Web Encryption (JWE):

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ

This can be decoded using the following Go program, which takes input from stdin and outputs the decoded (but not verified) contents:

package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"strings"
)

func PrettyString(str []byte) (string, error) {
	var prettyJSON bytes.Buffer
	if err := json.Indent(&prettyJSON, str, "", "  "); err != nil {
		return "", err
	}
	return prettyJSON.String(), nil
}

func main() {
	data, err := io.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	}

	segments := strings.Split(string(data), ".")
	for i, segment := range segments {
		if i == 2 {
			break
		}

		bytes, err := base64.RawURLEncoding.DecodeString(segment)
		if err != nil {
			fmt.Printf("Error decoding string: %s ", err.Error())
			return
		}

		pretty, err := PrettyString(bytes)
		if err != nil {
			panic(err)
		}

		fmt.Println(pretty)

		if i == 0 {
			// give us a generic object to interact with
			decoded := make(map[string](interface{}))
			err = json.Unmarshal([]byte(bytes), &decoded)
			if err != nil {
				panic(err)
			}
			// don't decode further if this is an encrypted JWT (JWE)
			if _, ok := decoded["enc"]; ok {
				break
			}
		}
	}
}

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #go #command-line #jwt #json #pretty-print.

Also on:

This post was filed under articles.

This post is part of the series pretty-print-jwt.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.