Skip to content

Instantly share code, notes, and snippets.

@mikerowehl
Created October 24, 2020 20:58
Show Gist options
  • Save mikerowehl/3094498f6227571c736d3662e4cb2ae5 to your computer and use it in GitHub Desktop.
Save mikerowehl/3094498f6227571c736d3662e4cb2ae5 to your computer and use it in GitHub Desktop.
Validating a JWT from Google Sign-in using jwt-go
package main
import (
"encoding/json"
"fmt"
"gopkg.in/dgrijalva/jwt-go.v3"
"io/ioutil"
"net/http"
"os"
)
func pemForKid(kid string) (pem string, err error) {
url := "https://www.googleapis.com/oauth2/v1/certs"
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
keys := map[string]string{}
err = json.Unmarshal(body, &keys)
if err != nil {
return
}
pem = keys[kid]
return
}
func main() {
token, err := jwt.Parse(os.Args[1], func(token *jwt.Token) (interface{}, error) {
// Google tokens use the RS256 version, with is RSA signing
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// Now download the PEMs from Google and pick the one that matches our token
verifyPem, err := pemForKid(token.Header["kid"].(string))
if err != nil {
return nil, fmt.Errorf("Error fetching verification key: %v\n", err)
}
// Parse the verification PEM to pull out the key, easy mode using the
// convenience functions provided by jwt-go
verifyKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(verifyPem))
if err != nil {
fmt.Printf("Error parsing key %v\n", err)
}
return verifyKey, nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
fmt.Printf("token %v\n", claims)
} else {
fmt.Printf("err %v\n", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment