We have a JWT token that we need to decode, the issue is that we are using TinyGo and some libraries are not supported, How can it be done for TinyGo / core Go libraries which is already supported? I want to print the "name" value:
I'm not able to get the name, any idea?
func main() {
token := `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`
base64String := base64.StdEncoding.EncodeToString([]byte(token))
decodedData, err := base64.StdEncoding.DecodeString(base64String)
if err != nil {
panic(err)
}
name := decodedData["name"]
fmt.Println(name)
}
The decoded token is:
PAYLOAD
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
See this example token from https://jwt.io
Decoding and getting the name
part is easy. But this does not ensure the token is valid, meaning the owner of the token is truly what the name says!
JWT tokens just contain the base64 encoded forms of a header, payload and signature parts, connected with a .
. So just split the token by .
, decode the base64 string and you may use json.Unmarshal()
to convert the header and playload parts to maps or structs.
You must verify the signature to ensure the name is valid. If you don't perform signature verification, a token may easily be forged to pose as anyone. Signature verification is exactly what JWT libs do (besides parsing and generating tokens). How to do that, check the sources of JWT libs. I also believe there are open-source libs that process JWT tokens that also work with tiny-go.
Example code to decode the parts and print the name
:
token := `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`
for i, part := range strings.Split(token, ".") {
fmt.Printf("[%d] part: %s\n", i, part)
decoded, err := base64.RawURLEncoding.DecodeString(part)
if err != nil {
panic(err)
}
fmt.Println("decoded:", string(decoded))
if i != 1 {
continue // i == 1 is the payload
}
var m map[string]interface{}
if err := json.Unmarshal(decoded, &m); err != nil {
fmt.Println("json decoding failed:", err)
continue
}
if name, ok := m["name"]; ok {
fmt.Println("name:", name)
}
}
Which outputs (try it on the Go Playground):
[0] part: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
decoded: {"alg":"HS256","typ":"JWT"}
[1] part: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
decoded: {"sub":"1234567890","name":"John Doe","iat":1516239022}
name: John Doe
[2] part: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
decoded: I�J�IHNJ(]�O���lj~�:N�%_�u,×