Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse the expiration date of a JWT to a time.Time() in Go?

I'd like to parse the expiration date (exp) from a JSON Web Token (JWT) without verifying it. I've tried the following script (in an attempt to follow How to parse unix timestamp to time.Time):

package main

import (
    "fmt"
    "log"
    "strconv"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
)

func main() {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

    token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
    if err != nil {
        log.Fatal(err)
    }

    if claims, ok := token.Claims.(jwt.MapClaims); ok {
        fmt.Println(claims["exp"])
        i, err := strconv.ParseInt(claims["exp"].(string), 10, 64)
        if err != nil {
            log.Fatal(err)
        }

        tm := time.Unix(i, 0)
        fmt.Println(tm)
    }
}

However, I get this error:

> go run main.go
<nil>
panic: interface conversion: interface {} is nil, not string

goroutine 1 [running]:
main.main()
    /Users/kurt/go/src/github.com/khpeek/mygoproject/jwt_validation/main.go:23 +0x34a
exit status 2

Is there a way I could get a string for exp out of the jwt library? How could I make this give me the expiration date (or the iat) of the JWT?

like image 882
Kurt Peek Avatar asked Oct 16 '22 10:10

Kurt Peek


1 Answers

I ended up calling int64 on claims["exp"] directly rather than first trying to convert it to a string:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
)

func main() {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

    token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
    if err != nil {
        log.Fatal(err)
    }

    claims, ok := token.Claims.(jwt.MapClaims)
    if !ok {
        log.Fatalf("Can't convert token's claims to standard claims")
    }

    var tm time.Time
    switch iat := claims["iat"].(type) {
    case float64:
        tm = time.Unix(int64(iat), 0)
    case json.Number:
        v, _ := iat.Int64()
        tm = time.Unix(v, 0)
    }

    fmt.Println(tm)
}

which prints

> go run main.go
2018-01-17 17:30:22 -0800 PST

Note that I've replaced exp with iat since the simplified example (obtained from jwt.io) does not have an exp claim, but it does have an iat one.

like image 103
Kurt Peek Avatar answered Oct 20 '22 21:10

Kurt Peek