README

jwt (JSON Web Token for Go)

JWT compatible

Github Actions Status Go Report Card GoDoc Version compatibility with Go 1.11 onward using modules

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 (not yet but is in the roadmap, see #17). Instead, JWS is used, narrowed down to the JWT specification.

Supported signing methods
SHA-256 SHA-384 SHA-512
HMAC ✔️ ✔️ ✔️
RSA ✔️ ✔️ ✔️
RSA-PSS ✔️ ✔️ ✔️
ECDSA ✔️ ✔️ ✔️
EdDSA ✔️

Important

Branch master is unstable, always use tagged versions. That way it is possible to differentiate pre-release tags from production ones. In other words, API changes all the time in master. It's a place for public experiment. Thus, make use of the latest stable version via Go modules.

Usage

Full documentation here.

Installing
Important

For Go 1.11, make sure the environment variable GO111MODULE is set as on when running the install command.

$ go get -u github.com/gbrlsnchs/jwt/v3
Signing
import (
	"time"

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

type CustomPayload struct {
	jwt.Payload
	Foo string `json:"foo,omitempty"`
	Bar int    `json:"bar,omitempty"`
}

var hs = jwt.NewHS256([]byte("secret"))

func main() {
	now := time.Now()
	pl := CustomPayload{
		Payload: jwt.Payload{
			Issuer:         "gbrlsnchs",
			Subject:        "someone",
			Audience:       jwt.Audience{"https://golang.org", "https://jwt.io"},
			ExpirationTime: jwt.NumericDate(now.Add(24 * 30 * 12 * time.Hour)),
			NotBefore:      jwt.NumericDate(now.Add(30 * time.Minute)),
			IssuedAt:       jwt.NumericDate(now),
			JWTID:          "foobar",
		},
		Foo: "foo",
		Bar: 1337,
	}

	token, err := jwt.Sign(pl, hs)
	if err != nil {
		// ...
	}

	// ...
}
Verifying
import "github.com/gbrlsnchs/jwt/v3"

type CustomPayload struct {
	jwt.Payload
	Foo string `json:"foo,omitempty"`
	Bar int    `json:"bar,omitempty"`
}

var hs = jwt.NewHS256([]byte("secret"))

func main() {
	// ...

	var pl CustomPayload
	hd, err := jwt.Verify(token, hs, &pl)
	if err != nil {
		// ...
	}

	// ...
}
Other use case examples
Setting "cty" and "kid" claims

The "cty" and "kid" claims can be set by passing options to the jwt.Sign function:

import (
	"time"

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

var hs = jwt.NewHS256([]byte("secret"))

func main() {
	pl := jwt.Payload{
		Subject:  "gbrlsnchs",
		Issuer:   "gsr.dev",
		IssuedAt: jwt.NumericDate(time.Now()),
	}

	token, err := jwt.Sign(pl, hs, jwt.ContentType("JWT"), jwt.KeyID("my_key"))
	if err != nil {
		// ...
	}

	// ...
}

Validating claims

import (
	"time"

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

type CustomPayload struct {
	jwt.Payload
	Foo string `json:"foo,omitempty"`
	Bar int    `json:"bar,omitempty"`
}

var hs = jwt.NewHS256([]byte("secret"))

func main() {
	// ...

	var (
		now = time.Now()
		aud = jwt.Audience{"https://golang.org"}

		// Validate claims "iat", "exp" and "aud".
		iatValidator = jwt.IssuedAtValidator(now)
		expValidator = jwt.ExpirationTimeValidator(now)
		audValidator = jwt.AudienceValidator(aud)

		// Use jwt.ValidatePayload to build a jwt.VerifyOption.
		// Validators are run in the order informed.
		pl              CustomPayload
		validatePayload = jwt.ValidatePayload(&pl.Payload, iatValidator, expValidator, audValidator)
	)

	hd, err := jwt.Verify(token, hs, &pl, validatePayload)
	if err != nil {
		// ...
	}

	// ...
}

Validating "alg" before verifying

For validating the "alg" field in a JOSE header before verification, the jwt.ValidateHeader option must be passed to jwt.Verify.

import "github.com/gbrlsnchs/jwt/v3"

var hs = jwt.NewHS256([]byte("secret"))

func main() {
	// ...

	var pl jwt.Payload
	if _, err := jwt.Verify(token, hs, &pl, jwt.ValidateHeader); err != nil {
		// ...
	}

	// ...
}

Using an Algorithm resolver

import (
	"errors"

	"github.com/gbrlsnchs/jwt/v3"
	"github.com/gbrlsnchs/jwt/v3/jwtutil"
)

var (
	// ...

	rs256 = jwt.NewRS256(jwt.RSAPublicKey(myRSAPublicKey))
	es256 = jwt.NewES256(jwt.ECDSAPublicKey(myECDSAPublicKey))
)

func main() {
	rv := &jwtutil.Resolver{New: func(hd jwt.Header) (jwt.Algorithm, error) {
		switch hd.KeyID {
		case "foo":
			return rs256, nil
		case "bar":
			return es256, nil
		default:
			return nil, errors.New(`invalid "kid"`)
		}
	}}
	var pl jwt.Payload
	if _, err := jwt.Verify(token, rv, &pl); err != nil {
		// ...
	}

	// ...
}

Contributing

How to help

Documentation

Overview

    Package jwt is a JSON Web Token signer, verifier and validator.

    Index

    Constants

    This section is empty.

    Variables

    View Source
    var (
    	// ErrECDSANilPrivKey is the error for trying to sign a JWT with a nil private key.
    	ErrECDSANilPrivKey = internal.NewError("jwt: ECDSA private key is nil")
    	// ErrECDSANilPubKey is the error for trying to verify a JWT with a nil public key.
    	ErrECDSANilPubKey = internal.NewError("jwt: ECDSA public key is nil")
    	// ErrECDSAVerification is the error for an invalid ECDSA signature.
    	ErrECDSAVerification = internal.NewError("jwt: ECDSA verification failed")
    )
    View Source
    var (
    	// ErrEd25519NilPrivKey is the error for trying to sign a JWT with a nil private key.
    	ErrEd25519NilPrivKey = internal.NewError("jwt: Ed25519 private key is nil")
    	// ErrEd25519NilPubKey is the error for trying to verify a JWT with a nil public key.
    	ErrEd25519NilPubKey = internal.NewError("jwt: Ed25519 public key is nil")
    	// ErrEd25519Verification is the error for when verification with Ed25519 fails.
    	ErrEd25519Verification = internal.NewError("jwt: Ed25519 verification failed")
    )
    View Source
    var (
    	// ErrHMACMissingKey is the error for trying to sign or verify a JWT with an empty key.
    	ErrHMACMissingKey = internal.NewError("jwt: HMAC key is empty")
    	// ErrHMACVerification is the error for an invalid signature.
    	ErrHMACVerification = internal.NewError("jwt: HMAC verification failed")
    )
    View Source
    var (
    	// ErrRSANilPrivKey is the error for trying to sign a JWT with a nil private key.
    	ErrRSANilPrivKey = internal.NewError("jwt: RSA private key is nil")
    	// ErrRSANilPubKey is the error for trying to verify a JWT with a nil public key.
    	ErrRSANilPubKey = internal.NewError("jwt: RSA public key is nil")
    	// ErrRSAVerification is the error for an invalid RSA signature.
    	ErrRSAVerification = internal.NewError("jwt: RSA verification failed")
    )
    View Source
    var (
    	// ErrAudValidation is the error for an invalid "aud" claim.
    	ErrAudValidation = internal.NewError("jwt: aud claim is invalid")
    	// ErrExpValidation is the error for an invalid "exp" claim.
    	ErrExpValidation = internal.NewError("jwt: exp claim is invalid")
    	// ErrIatValidation is the error for an invalid "iat" claim.
    	ErrIatValidation = internal.NewError("jwt: iat claim is invalid")
    	// ErrIssValidation is the error for an invalid "iss" claim.
    	ErrIssValidation = internal.NewError("jwt: iss claim is invalid")
    	// ErrJtiValidation is the error for an invalid "jti" claim.
    	ErrJtiValidation = internal.NewError("jwt: jti claim is invalid")
    	// ErrNbfValidation is the error for an invalid "nbf" claim.
    	ErrNbfValidation = internal.NewError("jwt: nbf claim is invalid")
    	// ErrSubValidation is the error for an invalid "sub" claim.
    	ErrSubValidation = internal.NewError("jwt: sub claim is invalid")
    )
    View Source
    var ErrAlgValidation = internal.NewError(`invalid "alg" field`)

      ErrAlgValidation indicates an incoming JWT's "alg" field mismatches the Validator's.

      View Source
      var ErrMalformed = internal.NewError("jwt: malformed token")

        ErrMalformed indicates a token doesn't have a valid format, as per the RFC 7519.

        View Source
        var ErrNotJSONObject = errors.New("jwt: payload is not a valid JSON object")

          ErrNotJSONObject is the error for when a JWT payload is not a JSON object.

          Functions

          func ECDSAPrivateKey

          func ECDSAPrivateKey(priv *ecdsa.PrivateKey) func(*ECDSASHA)

            ECDSAPrivateKey is an option to set a private key to the ECDSA-SHA algorithm.

            func ECDSAPublicKey

            func ECDSAPublicKey(pub *ecdsa.PublicKey) func(*ECDSASHA)

              ECDSAPublicKey is an option to set a public key to the ECDSA-SHA algorithm.

              func Ed25519PrivateKey

              func Ed25519PrivateKey(priv ed25519.PrivateKey) func(*Ed25519)

                Ed25519PrivateKey is an option to set a private key to the Ed25519 algorithm.

                func Ed25519PublicKey

                func Ed25519PublicKey(pub ed25519.PublicKey) func(*Ed25519)

                  Ed25519PublicKey is an option to set a public key to the Ed25519 algorithm.

                  func RSAPrivateKey

                  func RSAPrivateKey(priv *rsa.PrivateKey) func(*RSASHA)

                    RSAPrivateKey is an option to set a private key to the RSA-SHA algorithm.

                    func RSAPublicKey

                    func RSAPublicKey(pub *rsa.PublicKey) func(*RSASHA)

                      RSAPublicKey is an option to set a public key to the RSA-SHA algorithm.

                      func Sign

                      func Sign(payload interface{}, alg Algorithm, opts ...SignOption) ([]byte, error)

                        Sign signs a payload with alg.

                        func ValidateHeader

                        func ValidateHeader(rt *RawToken) error

                          ValidateHeader checks whether the algorithm contained in the JOSE header is the same used by the algorithm.

                          Types

                          type Algorithm

                          type Algorithm interface {
                          	Name() string
                          	Sign(headerPayload []byte) ([]byte, error)
                          	Size() int
                          	Verify(headerPayload, sig []byte) error
                          }

                            Algorithm is an algorithm for both signing and verifying a JWT.

                            func None

                            func None() Algorithm

                              None returns a dull, unsecured algorithm.

                              type Audience

                              type Audience []string

                                Audience is a special claim that may either be a single string or an array of strings, as per the RFC 7519.

                                func (Audience) MarshalJSON

                                func (a Audience) MarshalJSON() ([]byte, error)

                                  MarshalJSON implements a marshaling function for "aud" claim.

                                  func (*Audience) UnmarshalJSON

                                  func (a *Audience) UnmarshalJSON(b []byte) error

                                    UnmarshalJSON implements an unmarshaling function for "aud" claim.

                                    type ECDSASHA

                                    type ECDSASHA struct {
                                    	// contains filtered or unexported fields
                                    }

                                      ECDSASHA is an algorithm that uses ECDSA to sign SHA hashes.

                                      func NewES256

                                      func NewES256(opts ...func(*ECDSASHA)) *ECDSASHA

                                        NewES256 creates a new algorithm using ECDSA and SHA-256.

                                        func NewES384

                                        func NewES384(opts ...func(*ECDSASHA)) *ECDSASHA

                                          NewES384 creates a new algorithm using ECDSA and SHA-384.

                                          func NewES512

                                          func NewES512(opts ...func(*ECDSASHA)) *ECDSASHA

                                            NewES512 creates a new algorithm using ECDSA and SHA-512.

                                            func (*ECDSASHA) Name

                                            func (es *ECDSASHA) Name() string

                                              Name returns the algorithm's name.

                                              func (*ECDSASHA) Sign

                                              func (es *ECDSASHA) Sign(headerPayload []byte) ([]byte, error)

                                                Sign signs headerPayload using the ECDSA-SHA algorithm.

                                                func (*ECDSASHA) Size

                                                func (es *ECDSASHA) Size() int

                                                  Size returns the signature's byte size.

                                                  func (*ECDSASHA) Verify

                                                  func (es *ECDSASHA) Verify(headerPayload, sig []byte) (err error)

                                                    Verify verifies a signature based on headerPayload using ECDSA-SHA.

                                                    type Ed25519

                                                    type Ed25519 struct {
                                                    	// contains filtered or unexported fields
                                                    }

                                                      Ed25519 is an algorithm that uses EdDSA to sign SHA-512 hashes.

                                                      func NewEd25519

                                                      func NewEd25519(opts ...func(*Ed25519)) *Ed25519

                                                        NewEd25519 creates a new algorithm using EdDSA and SHA-512.

                                                        func (*Ed25519) Name

                                                        func (*Ed25519) Name() string

                                                          Name returns the algorithm's name.

                                                          func (*Ed25519) Sign

                                                          func (ed *Ed25519) Sign(headerPayload []byte) ([]byte, error)

                                                            Sign signs headerPayload using the Ed25519 algorithm.

                                                            func (*Ed25519) Size

                                                            func (*Ed25519) Size() int

                                                              Size returns the signature byte size.

                                                              func (*Ed25519) Verify

                                                              func (ed *Ed25519) Verify(payload, sig []byte) (err error)

                                                                Verify verifies a payload and a signature.

                                                                type HMACSHA

                                                                type HMACSHA struct {
                                                                	// contains filtered or unexported fields
                                                                }

                                                                  HMACSHA is an algorithm that uses HMAC to sign SHA hashes.

                                                                  func NewHS256

                                                                  func NewHS256(key []byte) *HMACSHA

                                                                    NewHS256 creates a new algorithm using HMAC and SHA-256.

                                                                    func NewHS384

                                                                    func NewHS384(key []byte) *HMACSHA

                                                                      NewHS384 creates a new algorithm using HMAC and SHA-384.

                                                                      func NewHS512

                                                                      func NewHS512(key []byte) *HMACSHA

                                                                        NewHS512 creates a new algorithm using HMAC and SHA-512.

                                                                        func (*HMACSHA) Name

                                                                        func (hs *HMACSHA) Name() string

                                                                          Name returns the algorithm's name.

                                                                          func (*HMACSHA) Sign

                                                                          func (hs *HMACSHA) Sign(headerPayload []byte) ([]byte, error)

                                                                            Sign signs headerPayload using the HMAC-SHA algorithm.

                                                                            func (*HMACSHA) Size

                                                                            func (hs *HMACSHA) Size() int

                                                                              Size returns the signature's byte size.

                                                                              func (*HMACSHA) Verify

                                                                              func (hs *HMACSHA) Verify(headerPayload, sig []byte) (err error)

                                                                                Verify verifies a signature based on headerPayload using HMAC-SHA.

                                                                                type Header struct {
                                                                                	Algorithm   string `json:"alg,omitempty"`
                                                                                	ContentType string `json:"cty,omitempty"`
                                                                                	KeyID       string `json:"kid,omitempty"`
                                                                                	Type        string `json:"typ,omitempty"`
                                                                                }

                                                                                  Header is a JOSE header narrowed down to the JWT specification from RFC 7519.

                                                                                  Parameters are ordered according to the RFC 7515.

                                                                                  func Verify

                                                                                  func Verify(token []byte, alg Algorithm, payload interface{}, opts ...VerifyOption) (Header, error)

                                                                                    Verify verifies a token's signature using alg. Before verification, opts is iterated and each option in it is run.

                                                                                    type Payload

                                                                                    type Payload struct {
                                                                                    	Issuer         string   `json:"iss,omitempty"`
                                                                                    	Subject        string   `json:"sub,omitempty"`
                                                                                    	Audience       Audience `json:"aud,omitempty"`
                                                                                    	ExpirationTime *Time    `json:"exp,omitempty"`
                                                                                    	NotBefore      *Time    `json:"nbf,omitempty"`
                                                                                    	IssuedAt       *Time    `json:"iat,omitempty"`
                                                                                    	JWTID          string   `json:"jti,omitempty"`
                                                                                    }

                                                                                      Payload is a JWT payload according to the RFC 7519.

                                                                                      type RSASHA

                                                                                      type RSASHA struct {
                                                                                      	// contains filtered or unexported fields
                                                                                      }

                                                                                        RSASHA is an algorithm that uses RSA to sign SHA hashes.

                                                                                        func NewPS256

                                                                                        func NewPS256(opts ...func(*RSASHA)) *RSASHA

                                                                                          NewPS256 creates a new algorithm using RSA-PSS and SHA-256.

                                                                                          func NewPS384

                                                                                          func NewPS384(opts ...func(*RSASHA)) *RSASHA

                                                                                            NewPS384 creates a new algorithm using RSA-PSS and SHA-384.

                                                                                            func NewPS512

                                                                                            func NewPS512(opts ...func(*RSASHA)) *RSASHA

                                                                                              NewPS512 creates a new algorithm using RSA-PSS and SHA-512.

                                                                                              func NewRS256

                                                                                              func NewRS256(opts ...func(*RSASHA)) *RSASHA

                                                                                                NewRS256 creates a new algorithm using RSA and SHA-256.

                                                                                                func NewRS384

                                                                                                func NewRS384(opts ...func(*RSASHA)) *RSASHA

                                                                                                  NewRS384 creates a new algorithm using RSA and SHA-384.

                                                                                                  func NewRS512

                                                                                                  func NewRS512(opts ...func(*RSASHA)) *RSASHA

                                                                                                    NewRS512 creates a new algorithm using RSA and SHA-512.

                                                                                                    func (*RSASHA) Name

                                                                                                    func (rs *RSASHA) Name() string

                                                                                                      Name returns the algorithm's name.

                                                                                                      func (*RSASHA) Sign

                                                                                                      func (rs *RSASHA) Sign(headerPayload []byte) ([]byte, error)

                                                                                                        Sign signs headerPayload using either RSA-SHA or RSA-PSS-SHA algorithms.

                                                                                                        func (*RSASHA) Size

                                                                                                        func (rs *RSASHA) Size() int

                                                                                                          Size returns the signature's byte size.

                                                                                                          func (*RSASHA) Verify

                                                                                                          func (rs *RSASHA) Verify(headerPayload, sig []byte) (err error)

                                                                                                            Verify verifies a signature based on headerPayload using either RSA-SHA or RSA-PSS-SHA.

                                                                                                            type RawToken

                                                                                                            type RawToken struct {
                                                                                                            	// contains filtered or unexported fields
                                                                                                            }

                                                                                                              RawToken is a representation of a parsed JWT string.

                                                                                                              type Resolver

                                                                                                              type Resolver interface {
                                                                                                              	Resolve(Header) error
                                                                                                              }

                                                                                                                Resolver is an Algorithm that needs to set some variables based on a Header before performing signing and verification.

                                                                                                                type SignOption

                                                                                                                type SignOption func(*Header)

                                                                                                                  SignOption is a functional option for signing.

                                                                                                                  func ContentType

                                                                                                                  func ContentType(cty string) SignOption

                                                                                                                    ContentType sets the "cty" claim for a Header before signing.

                                                                                                                    func KeyID

                                                                                                                    func KeyID(kid string) SignOption

                                                                                                                      KeyID sets the "kid" claim for a Header before signing.

                                                                                                                      type Time

                                                                                                                      type Time struct {
                                                                                                                      	time.Time
                                                                                                                      }

                                                                                                                        Time is the allowed format for time, as per the RFC 7519.

                                                                                                                        func NumericDate

                                                                                                                        func NumericDate(tt time.Time) *Time

                                                                                                                          NumericDate is a resolved Unix time.

                                                                                                                          func (Time) MarshalJSON

                                                                                                                          func (t Time) MarshalJSON() ([]byte, error)

                                                                                                                            MarshalJSON implements a marshaling function for time-related claims.

                                                                                                                            func (*Time) UnmarshalJSON

                                                                                                                            func (t *Time) UnmarshalJSON(b []byte) error

                                                                                                                              UnmarshalJSON implements an unmarshaling function for time-related claims.

                                                                                                                              type Validator

                                                                                                                              type Validator func(*Payload) error

                                                                                                                                Validator is a function that validates a Payload pointer.

                                                                                                                                func AudienceValidator

                                                                                                                                func AudienceValidator(aud Audience) Validator

                                                                                                                                  AudienceValidator validates the "aud" claim. It checks if at least one of the audiences in the JWT's payload is listed in aud.

                                                                                                                                  func ExpirationTimeValidator

                                                                                                                                  func ExpirationTimeValidator(now time.Time) Validator

                                                                                                                                    ExpirationTimeValidator validates the "exp" claim.

                                                                                                                                    func IDValidator

                                                                                                                                    func IDValidator(jti string) Validator

                                                                                                                                      IDValidator validates the "jti" claim.

                                                                                                                                      func IssuedAtValidator

                                                                                                                                      func IssuedAtValidator(now time.Time) Validator

                                                                                                                                        IssuedAtValidator validates the "iat" claim.

                                                                                                                                        func IssuerValidator

                                                                                                                                        func IssuerValidator(iss string) Validator

                                                                                                                                          IssuerValidator validates the "iss" claim.

                                                                                                                                          func NotBeforeValidator

                                                                                                                                          func NotBeforeValidator(now time.Time) Validator

                                                                                                                                            NotBeforeValidator validates the "nbf" claim.

                                                                                                                                            func SubjectValidator

                                                                                                                                            func SubjectValidator(sub string) Validator

                                                                                                                                              SubjectValidator validates the "sub" claim.

                                                                                                                                              type VerifyOption

                                                                                                                                              type VerifyOption func(*RawToken) error

                                                                                                                                                VerifyOption is a functional option for verifying.

                                                                                                                                                func ValidatePayload

                                                                                                                                                func ValidatePayload(pl *Payload, vds ...Validator) VerifyOption

                                                                                                                                                  ValidatePayload runs validators against a Payload after it's been decoded.

                                                                                                                                                  Directories

                                                                                                                                                  Path Synopsis