README
jwt (JSON Web Token for Go)
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
- For bugs and opinions, please open an issue
- For pushing changes, please open a pull request
Documentation
Overview ¶
Package jwt is a JSON Web Token signer, verifier and validator.
Index ¶
- Variables
- func ECDSAPrivateKey(priv *ecdsa.PrivateKey) func(*ECDSASHA)
- func ECDSAPublicKey(pub *ecdsa.PublicKey) func(*ECDSASHA)
- func Ed25519PrivateKey(priv ed25519.PrivateKey) func(*Ed25519)
- func Ed25519PublicKey(pub ed25519.PublicKey) func(*Ed25519)
- func RSAPrivateKey(priv *rsa.PrivateKey) func(*RSASHA)
- func RSAPublicKey(pub *rsa.PublicKey) func(*RSASHA)
- func Sign(payload interface{}, alg Algorithm, opts ...SignOption) ([]byte, error)
- func ValidateHeader(rt *RawToken) error
- type Algorithm
- type Audience
- type ECDSASHA
- type Ed25519
- type HMACSHA
- type Header
- type Payload
- type RSASHA
- type RawToken
- type Resolver
- type SignOption
- type Time
- type Validator
- func AudienceValidator(aud Audience) Validator
- func ExpirationTimeValidator(now time.Time) Validator
- func IDValidator(jti string) Validator
- func IssuedAtValidator(now time.Time) Validator
- func IssuerValidator(iss string) Validator
- func NotBeforeValidator(now time.Time) Validator
- func SubjectValidator(sub string) Validator
- type VerifyOption
Constants ¶
Variables ¶
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") )
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") )
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") )
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") )
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") )
var ErrAlgValidation = internal.NewError(`invalid "alg" field`)
ErrAlgValidation indicates an incoming JWT's "alg" field mismatches the Validator's.
var ErrMalformed = internal.NewError("jwt: malformed token")
ErrMalformed indicates a token doesn't have a valid format, as per the RFC 7519.
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 ¶
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 ¶
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 ¶
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 ¶
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.
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 ¶
MarshalJSON implements a marshaling function for "aud" claim.
func (*Audience) UnmarshalJSON ¶
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.
type Ed25519 ¶
type Ed25519 struct {
// contains filtered or unexported fields
}
Ed25519 is an algorithm that uses EdDSA to sign SHA-512 hashes.
func NewEd25519 ¶
NewEd25519 creates a new algorithm using EdDSA and SHA-512.
type HMACSHA ¶
type HMACSHA struct {
// contains filtered or unexported fields
}
HMACSHA is an algorithm that uses HMAC to sign SHA hashes.
type Header ¶
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.
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.
type RawToken ¶
type RawToken struct {
// contains filtered or unexported fields
}
RawToken is a representation of a parsed JWT string.
type Resolver ¶
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 ¶
Time is the allowed format for time, as per the RFC 7519.
func (Time) MarshalJSON ¶
MarshalJSON implements a marshaling function for time-related claims.
func (*Time) UnmarshalJSON ¶
UnmarshalJSON implements an unmarshaling function for time-related claims.
type Validator ¶
Validator is a function that validates a Payload pointer.
func AudienceValidator ¶
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 ¶
ExpirationTimeValidator validates the "exp" claim.
func IssuedAtValidator ¶
IssuedAtValidator validates the "iat" claim.
func IssuerValidator ¶
IssuerValidator validates the "iss" claim.
func NotBeforeValidator ¶
NotBeforeValidator validates the "nbf" claim.
func SubjectValidator ¶
SubjectValidator validates the "sub" claim.
type VerifyOption ¶
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.