@@ -6,7 +6,10 @@ package cmd
66
77import (
88 "context"
9+ "encoding/base64"
10+ "encoding/json"
911 "fmt"
12+ "strings"
1013 "time"
1114
1215 connect "github.com/bufbuild/connect-go"
@@ -23,6 +26,7 @@ import (
2326
2427var idpTokenOpts struct {
2528 Audience []string
29+ Decode bool
2630}
2731
2832var idpTokenCmd = & cobra.Command {
@@ -35,6 +39,56 @@ var idpTokenCmd = &cobra.Command{
3539 defer cancel ()
3640
3741 tkn , err := idpToken (ctx , idpTokenOpts .Audience )
42+
43+ // If the user wants to decode the token, then do so.
44+ if idpTokenOpts .Decode {
45+ // Split the token into its three parts.
46+ parts := strings .Split (tkn , "." )
47+ if len (parts ) != 3 {
48+ xerrors .Errorf ("JWT token is not valid" )
49+ }
50+
51+ // Decode the header.
52+ header , err := base64 .RawURLEncoding .DecodeString (parts [0 ])
53+ if err != nil {
54+ xerrors .Errorf ("Failed to decode header: " , err )
55+ }
56+
57+ // Decode the payload.
58+ payload , err := base64 .RawURLEncoding .DecodeString (parts [1 ])
59+ if err != nil {
60+ xerrors .Errorf ("Failed to decode payload: " , err )
61+ }
62+
63+ // Unmarshal the header and payload into JSON.
64+ var headerJSON map [string ]interface {}
65+ var payloadJSON map [string ]interface {}
66+
67+ // This function unmarshals the header and payload of a JWT.
68+ // The header is unmarshalled into a HeaderJSON struct, and the payload is unmarshalled into a PayloadJSON struct.
69+ if err := json .Unmarshal (header , & headerJSON ); err != nil {
70+ xerrors .Errorf ("Failed to unmarshal header: " , err )
71+ }
72+
73+ if err := json .Unmarshal (payload , & payloadJSON ); err != nil {
74+ xerrors .Errorf ("Failed to unmarshal payload: " , err )
75+ }
76+
77+ output := map [string ]interface {}{
78+ "Header" : headerJSON ,
79+ "Payload" : payloadJSON ,
80+ }
81+
82+ // The header and payload are then marshalled into a map and printed to the screen.
83+ outputPretty , err := json .MarshalIndent (output , "" , " " )
84+ if err != nil {
85+ xerrors .Errorf ("Failed to marshal output: " , err )
86+ }
87+
88+ fmt .Printf ("%s\n " , outputPretty )
89+ return nil
90+ }
91+
3892 if err != nil {
3993 return err
4094 }
@@ -86,4 +140,6 @@ func init() {
86140
87141 idpTokenCmd .Flags ().StringArrayVar (& idpTokenOpts .Audience , "audience" , nil , "audience of the ID token" )
88142 _ = idpTokenCmd .MarkFlagRequired ("audience" )
143+
144+ idpTokenCmd .Flags ().BoolVar (& idpTokenOpts .Decode , "decode" , false , "decode token to JSON" )
89145}
0 commit comments