Go JWT signing, verifying and validating
Clone or download
Permalink
Failed to load latest commit information.
.editorconfig Change EditorConfig setting Oct 2, 2018
.travis.yml Remove explicit declaration of env variable on Travis Oct 24, 2018
CHANGELOG.md Update the changelog for v2 release 🎉 Sep 14, 2018
LICENSE Fix license May 9, 2018
README.md Update README Oct 24, 2018
benchmark_test.go Adapt tests and examples to new JWT format Sep 4, 2018
build.go Fix appending a dot to signature Sep 3, 2018
byte_size.go Add byte size function Sep 9, 2018
decode.go Add decode function Sep 9, 2018
doc.go Readd doc.go Feb 15, 2018
ecdsa.go Use decode function in signers Sep 9, 2018
ecdsa_test.go Standardize signing methods error variables' names Sep 3, 2018
go.mod Update package module version and import it correctly in tests Sep 3, 2018
hash_size.go Use global encoder in hashSize function Aug 29, 2018
header.go Add support for setting "cty" header parameter Sep 13, 2018
hmac.go Use decode function in signers Sep 9, 2018
hmac_test.go Update HMAC tests Sep 3, 2018
joser.go Add interface for retrieving header Sep 4, 2018
jwt.go Add support for setting "cty" header parameter Sep 13, 2018
jwt_test.go Use math constant Sep 14, 2018
marshal.go Add Unmarshaler interface Sep 13, 2018
methods.go Fix documentation for method names Sep 3, 2018
none.go Adapt supported signers to new Signer interface signature Sep 3, 2018
none_test.go Add tests for "none" alg Sep 3, 2018
parse.go Update documentation for parse function Sep 9, 2018
parse_test.go Add tests that parse tokens issued by jwt.io Sep 13, 2018
rsa.go Use decode function in signers Sep 9, 2018
rsa_test.go Standardize signing methods error variables' names Sep 3, 2018
signer.go Add documentation for Signer interface methods Sep 3, 2018
unmarshal.go Add Unmarshaler interface Sep 13, 2018
validators.go Change validator's name Sep 4, 2018
validators_test.go Reorder validators tests Sep 13, 2018

README.md

jwt (JSON Web Token for Go)

JWT compatible

Build Status Sourcegraph GoDoc Minimal Version Join the chat at https://gitter.im/gbrlsnchs/jwt

About

This package is a JWT signer, verifier and validator for Go (or Golang).

Although there are many JWT packages out there for Go, many lack support for some signing, verifying or validation methods and, when they don't, they're overcomplicated. This package tries to mimic the ease of use from Node JWT library's API while following the Effective Go guidelines.

Support for JWE isn't provided. Instead, JWS is used, narrowed down to the JWT specification.

Usage

Full documentation here.

Installing

Go 1.10

vgo get -u github.com/gbrlsnchs/jwt/v2

Go 1.11 or after

go get -u github.com/gbrlsnchs/jwt/v2

Importing

import (
	// ...

	"github.com/gbrlsnchs/jwt/v2"
)

Signing a simple JWT

// Timestamp the beginning.
now := time.Now()
// Define a signer.
hs256 := jwt.NewHS256("secret")
jot := &jwt.JWT{
	Issuer:         "gbrlsnchs",
	Subject:        "someone",
	Audience:       "gophers",
	ExpirationTime: now.Add(24 * 30 * 12 * time.Hour).Unix(),
	NotBefore:      now.Add(30 * time.Minute).Unix(),
	IssuedAt:       now.Unix(),
	ID:             "foobar",
}
jot.SetAlgorithm(hs256)
jot.SetKeyID("kid")
payload, err := jwt.Marshal(jot)
if err != nil {
	// handle error
}
token, err := hs256.Sign(payload)
if err != nil {
	// handle error
}
log.Printf("token = %s", token)

Signing a JWT with public claims

First, create a custom type and embed a JWT pointer in it

type Token struct {
	*jwt.JWT
	IsLoggedIn  bool   `json:"isLoggedIn"`
	CustomField string `json:"customField,omitempty"`
}

Now initialize, marshal and sign it

// Timestamp the beginning.
now := time.Now()
// Define a signer.
hs256 := jwt.NewHS256("secret")
jot := &Token{
	JWT: &jwt.JWT{
		Issuer:         "gbrlsnchs",
		Subject:        "someone",
		Audience:       "gophers",
		ExpirationTime: now.Add(24 * 30 * 12 * time.Hour).Unix(),
		NotBefore:      now.Add(30 * time.Minute).Unix(),
		IssuedAt:       now.Unix(),
		ID:             "foobar",
	},
	IsLoggedIn:  true,
	CustomField: "myCustomField",
}
jot.SetAlgorithm(hs256)
jot.SetKeyID("kid")
payload, err := jwt.Marshal(jot)
if err != nil {
	// handle error
}
token, err := hs256.Sign(payload)
if err != nil {
	// handle error
}
log.Printf("token = %s", token)

Verifying and validating a JWT

// Timestamp the beginning.
now := time.Now()
// Define a signer.
hs256 := jwt.NewHS256("secret")
// This is a mocked token for demonstration purposes only.
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." +
	"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ." +
	"lZ1zDoGNAv3u-OclJtnoQKejE8_viHlMtGlAxE8AE0Q"

// First, extract the payload and signature.
// This enables unmarshaling the JWT first and
// verifying it later or vice versa.
payload, sig, err := jwt.Parse(token)
if err != nil {
	// handle error
}
if err = hs256.Verify(payload, sig); err != nil {
	// handle error
}
var jot Token
if err = jwt.Unmarshal(payload, &jot); err != nil {
	// handle error
}

// Validate fields.
iatValidator := jwt.IssuedAtValidator(now)
expValidator := jwt.ExpirationTimeValidator(now)
audValidator := jwt.AudienceValidator("admin")
if err = jot.Validate(iatValidator, expValidator, audValidator); err != nil {
	switch err {
	case jwt.ErrIatValidation:
		// handle "iat" validation error
	case jwt.ErrExpValidation:
		// handle "exp" validation error
	case jwt.ErrAudValidation:
		// handle "aud" validation error
	}
}

Contributing

How to help