HOWTO use JWT in Go

This is just a quick reminder about how I played with JSON Web Tokens in Go. Encryption using a pair of private/public keys is used.

package main

import (
    "errors"
    "fmt"
    "io/ioutil"

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

func keyfunc(token *jwt.Token) (interface{}, error) {
    kid := token.Header["kid"]
    str, ok := kid.(string)
    if !ok {
        return nil, errors.New("failed to get kid from token header")
    }
    pubPEM, err := ioutil.ReadFile(string(str))
    if err != nil {
        return nil, err
    }
    pubParsed, err := jwt.ParseRSAPublicKeyFromPEM(pubPEM)
    if err != nil {
        return nil, err
    }

    return pubParsed, nil
}

type sbcsClaims struct {
    Upn    string   `json:"upn"`
    Groups []string `json:"groups"`
    jwt.StandardClaims
}

func main() {

    // Private key.
    privPEM, err := ioutil.ReadFile("key.pem")
    if err != nil {
        panic(err)
    }
    privParsed, err := jwt.ParseRSAPrivateKeyFromPEM(privPEM)
    if err != nil {
        panic(err)
    }

    // Create JWT.
    stdClaims := jwt.StandardClaims{
        Issuer:    "Go Ticketserver 1.0",
        Id:        uuid.NewV4().String(),
        Subject:   "john.doe",
        ExpiresAt: 1521422680,
    }
    claims := sbcsClaims{
        Upn:    "john.doe@example.com",
        Groups: []string{"GROUP1", "GROUP2"},
    }
    claims.StandardClaims = stdClaims

    token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
    token.Header["kid"] = "key.pub.pem"
    signed, err := token.SignedString(privParsed)
    if err != nil {
        panic(err)
    }
    fmt.Println(signed)

    fmt.Println("====")

    // Validate JWT.
    parsedToken, err := jwt.Parse(signed, keyfunc)
    if err != nil {
        fmt.Println("token is invalid: ", err)
    } else {
        fmt.Println(parsedToken.Claims)
    }

}