jwt

package module
v4.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2022 License: MIT Imports: 19 Imported by: 27

README

jwt

build-img pkg-img reportcard-img coverage-img version-img

JSON Web Token for Go RFC 7519, also see jwt.io for more.

The latest version is v4.

Rationale

There are many JWT libraries, but many of them are hard to use (unclear or fixed API), not optimal (unneeded allocations + strange API). This library addresses all these issues. It's simple to read, to use, memory and CPU conservative.

Features

  • Simple API.
  • Clean and tested code.
  • Optimized for speed.
  • Concurrent-safe.
  • Dependency-free.
  • All well-known algorithms are supported
    • HMAC (HS)
    • RSA (RS)
    • RSA-PSS (PS)
    • ECDSA (ES)
    • EdDSA (EdDSA)
    • or your own!

See GUIDE.md for more details.

Install

Go version 1.17+

go get github.com/cristalhq/jwt/v4

Example

Build new token:

// create a Signer (HMAC in this example)
key := []byte(`secret`)
signer, err := jwt.NewSignerHS(jwt.HS256, key)
checkErr(err)

// create claims (you can create your own, see: Example_BuildUserClaims)
claims := &jwt.RegisteredClaims{
    Audience: []string{"admin"},
    ID:       "random-unique-string",
}

// create a Builder
builder := jwt.NewBuilder(signer)

// and build a Token
token, err := builder.Build(claims)
checkErr(err)

// here is token as a string
var _ string = token.String()

Parse and verify token:

// create a Verifier (HMAC in this example)
key := []byte(`secret`)
verifier, err := jwt.NewVerifierHS(jwt.HS256, key)
checkErr(err)

// parse and verify a token
tokenBytes := token.Bytes()
newToken, err := jwt.Parse(tokenBytes, verifier)
checkErr(err)

// or just verify it's signature
err = verifier.Verify(newToken)
checkErr(err)

// get Registered claims
var newClaims jwt.RegisteredClaims
errClaims := json.Unmarshal(newToken.Claims(), &newClaims)
checkErr(errClaims)

// or parse only claims
errParseClaims := jwt.ParseClaims(tokenBytes, verifier, &newClaims)
checkErr(errParseClaims)

// verify claims as you wish
var _ bool = newClaims.IsForAudience("admin")
var _ bool = newClaims.IsValidAt(time.Now())

Also see examples: example_test.go.

Documentation

See these docs.

License

MIT License.

Documentation

Overview

Package jwt represents JSON Web Token for Go.

Builder, all Signers and Verifiers are safe for use by multiple goroutines simultaneously.

See [RFC 7519](https://tools.ietf.org/html/rfc7519) and see [jwt.io](https://jwt.io) for more.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNilKey indicates that key is nil.
	ErrNilKey = errors.New("key is nil")

	// ErrInvalidKey indicates that key is not valid.
	ErrInvalidKey = errors.New("key is not valid")

	// ErrUnsupportedAlg indicates that given algorithm is not supported.
	ErrUnsupportedAlg = errors.New("algorithm is not supported")

	// ErrInvalidFormat indicates that token format is not valid.
	ErrInvalidFormat = errors.New("token format is not valid")

	// ErrAudienceInvalidFormat indicates that audience format is not valid.
	ErrAudienceInvalidFormat = errors.New("audience format is not valid")

	// ErrDateInvalidFormat indicates that date format is not valid.
	ErrDateInvalidFormat = errors.New("date is not valid")

	// ErrAlgorithmMismatch indicates that token is signed by another algorithm.
	ErrAlgorithmMismatch = errors.New("token is signed by another algorithm")

	// ErrInvalidSignature indicates that signature is not valid.
	ErrInvalidSignature = errors.New("signature is not valid")

	// ErrUninitializedToken indicates that token was not create with Parse func.
	ErrUninitializedToken = errors.New("token was not initialized")
)

JWT sign, verify, build and parse errors.

Functions

func GenerateRandomBits

func GenerateRandomBits(bits int) ([]byte, error)

Generates a random key of the given bits length.

func ParseClaims

func ParseClaims(raw []byte, verifier Verifier, claims interface{}) error

ParseClaims decodes a token claims and verifies it's signature.

Types

type Algorithm

type Algorithm string

Algorithm for signing and verifying.

const (
	EdDSA Algorithm = "EdDSA"

	HS256 Algorithm = "HS256"
	HS384 Algorithm = "HS384"
	HS512 Algorithm = "HS512"

	RS256 Algorithm = "RS256"
	RS384 Algorithm = "RS384"
	RS512 Algorithm = "RS512"

	ES256 Algorithm = "ES256"
	ES384 Algorithm = "ES384"
	ES512 Algorithm = "ES512"

	PS256 Algorithm = "PS256"
	PS384 Algorithm = "PS384"
	PS512 Algorithm = "PS512"
)

Algorithm names for signing and verifying.

func (Algorithm) String

func (a Algorithm) String() string

type Audience

type Audience []string

Audience is a special claim that be a single string or an array of strings See: https://tools.ietf.org/html/rfc7519

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 json.Unmarshaler interface.

type Builder

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

Builder is used to create a new token.

func NewBuilder

func NewBuilder(signer Signer, opts ...BuilderOption) *Builder

NewBuilder returns new instance of Builder.

func (*Builder) Build

func (b *Builder) Build(claims interface{}) (*Token, error)

Build used to create and encode JWT with a provided claims. If claims param is of type []byte or string then it's treated as a marshaled JSON. In other words you can pass already marshaled claims.

type BuilderOption

type BuilderOption func(*Builder)

BuilderOption is used to modify builder properties.

func WithContentType

func WithContentType(cty string) BuilderOption

WithContentType sets `cty` header for token.

func WithKeyID

func WithKeyID(kid string) BuilderOption

WithKeyID sets `kid` header for token.

type ESAlg

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

func NewSignerES

func NewSignerES(alg Algorithm, key *ecdsa.PrivateKey) (*ESAlg, error)

NewSignerES returns a new ECDSA-based signer.

func NewVerifierES

func NewVerifierES(alg Algorithm, key *ecdsa.PublicKey) (*ESAlg, error)

NewVerifierES returns a new ECDSA-based verifier.

func (*ESAlg) Algorithm

func (es *ESAlg) Algorithm() Algorithm

func (*ESAlg) Sign

func (es *ESAlg) Sign(payload []byte) ([]byte, error)

func (*ESAlg) SignSize

func (es *ESAlg) SignSize() int

func (*ESAlg) Verify

func (es *ESAlg) Verify(token *Token) error

type EdDSAAlg

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

func NewSignerEdDSA

func NewSignerEdDSA(key ed25519.PrivateKey) (*EdDSAAlg, error)

NewSignerEdDSA returns a new ed25519-based signer.

func NewVerifierEdDSA

func NewVerifierEdDSA(key ed25519.PublicKey) (*EdDSAAlg, error)

NewVerifierEdDSA returns a new ed25519-based verifier.

func (*EdDSAAlg) Algorithm

func (ed *EdDSAAlg) Algorithm() Algorithm

func (*EdDSAAlg) Sign

func (ed *EdDSAAlg) Sign(payload []byte) ([]byte, error)

func (*EdDSAAlg) SignSize

func (ed *EdDSAAlg) SignSize() int

func (*EdDSAAlg) Verify

func (ed *EdDSAAlg) Verify(token *Token) error

type HSAlg

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

func NewSignerHS

func NewSignerHS(alg Algorithm, key []byte) (*HSAlg, error)

NewSignerHS returns a new HMAC-based signer.

func NewVerifierHS

func NewVerifierHS(alg Algorithm, key []byte) (*HSAlg, error)

NewVerifierHS returns a new HMAC-based verifier.

func (*HSAlg) Algorithm

func (hs *HSAlg) Algorithm() Algorithm

func (*HSAlg) Sign

func (hs *HSAlg) Sign(payload []byte) ([]byte, error)

func (*HSAlg) SignSize

func (hs *HSAlg) SignSize() int

func (*HSAlg) Verify

func (hs *HSAlg) Verify(token *Token) error
type Header struct {
	Algorithm   Algorithm `json:"alg"`
	Type        string    `json:"typ,omitempty"` // only "JWT" can be here
	ContentType string    `json:"cty,omitempty"`
	KeyID       string    `json:"kid,omitempty"`
}

Header representa JWT header data. See: https://tools.ietf.org/html/rfc7519#section-5, https://tools.ietf.org/html/rfc7517

func (Header) MarshalJSON

func (h Header) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

type NumericDate

type NumericDate struct {
	time.Time
}

NumericDate represents date for StandardClaims See: https://tools.ietf.org/html/rfc7519#section-2

func NewNumericDate

func NewNumericDate(t time.Time) *NumericDate

NewNumericDate creates a new NumericDate value from time.Time.

func (NumericDate) MarshalJSON

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

MarshalJSON implements the json.Marshaler interface.

func (*NumericDate) UnmarshalJSON

func (t *NumericDate) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

type PSAlg

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

func NewSignerPS

func NewSignerPS(alg Algorithm, key *rsa.PrivateKey) (*PSAlg, error)

NewSignerPS returns a new RSA-PSS-based signer.

func NewVerifierPS

func NewVerifierPS(alg Algorithm, key *rsa.PublicKey) (*PSAlg, error)

NewVerifierPS returns a new RSA-PSS-based signer.

func (*PSAlg) Algorithm

func (ps *PSAlg) Algorithm() Algorithm

func (*PSAlg) Sign

func (ps *PSAlg) Sign(payload []byte) ([]byte, error)

func (*PSAlg) SignSize

func (ps *PSAlg) SignSize() int

func (*PSAlg) Verify

func (ps *PSAlg) Verify(token *Token) error

type RSAlg

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

func NewSignerRS

func NewSignerRS(alg Algorithm, key *rsa.PrivateKey) (*RSAlg, error)

NewSignerRS returns a new RSA-based signer.

func NewVerifierRS

func NewVerifierRS(alg Algorithm, key *rsa.PublicKey) (*RSAlg, error)

NewVerifierRS returns a new RSA-based verifier.

func (*RSAlg) Algorithm

func (rs *RSAlg) Algorithm() Algorithm

func (*RSAlg) Sign

func (rs *RSAlg) Sign(payload []byte) ([]byte, error)

func (*RSAlg) SignSize

func (rs *RSAlg) SignSize() int

func (*RSAlg) Verify

func (rs *RSAlg) Verify(token *Token) error

type RegisteredClaims

type RegisteredClaims struct {
	// ID claim provides a unique identifier for the JWT.
	ID string `json:"jti,omitempty"`

	// Audience claim identifies the recipients that the JWT is intended for.
	Audience Audience `json:"aud,omitempty"`

	// Issuer claim identifies the principal that issued the JWT.
	// Use of this claim is OPTIONAL.
	Issuer string `json:"iss,omitempty"`

	// Subject claim identifies the principal that is the subject of the JWT.
	// Use of this claim is OPTIONAL.
	Subject string `json:"sub,omitempty"`

	// ExpiresAt claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing.
	// Use of this claim is OPTIONAL.
	ExpiresAt *NumericDate `json:"exp,omitempty"`

	// IssuedAt claim identifies the time at which the JWT was issued.
	// This claim can be used to determine the age of the JWT.
	// Use of this claim is OPTIONAL.
	IssuedAt *NumericDate `json:"iat,omitempty"`

	// NotBefore claim identifies the time before which the JWT MUST NOT be accepted for processing.
	// Use of this claim is OPTIONAL.
	NotBefore *NumericDate `json:"nbf,omitempty"`
}

RegisteredClaims represents claims for JWT. See: https://tools.ietf.org/html/rfc7519#section-4.1

func (*RegisteredClaims) IsForAudience

func (sc *RegisteredClaims) IsForAudience(audience string) bool

IsForAudience reports whether token has a given audience.

func (*RegisteredClaims) IsID

func (sc *RegisteredClaims) IsID(id string) bool

IsID reports whether token has a given id.

func (*RegisteredClaims) IsIssuer

func (sc *RegisteredClaims) IsIssuer(issuer string) bool

IsIssuer reports whether token has a given issuer.

func (*RegisteredClaims) IsSubject

func (sc *RegisteredClaims) IsSubject(subject string) bool

IsSubject reports whether token has a given subject.

func (*RegisteredClaims) IsValidAt

func (sc *RegisteredClaims) IsValidAt(now time.Time) bool

IsValidAt reports whether a token is valid at a given time.

func (*RegisteredClaims) IsValidExpiresAt

func (sc *RegisteredClaims) IsValidExpiresAt(now time.Time) bool

IsValidExpiresAt reports whether a token isn't expired at a given time.

func (*RegisteredClaims) IsValidIssuedAt

func (sc *RegisteredClaims) IsValidIssuedAt(now time.Time) bool

IsValidIssuedAt reports whether a token was created before a given time.

func (*RegisteredClaims) IsValidNotBefore

func (sc *RegisteredClaims) IsValidNotBefore(now time.Time) bool

IsValidNotBefore reports whether a token isn't used before a given time.

type Signer

type Signer interface {
	Algorithm() Algorithm
	SignSize() int
	Sign(payload []byte) ([]byte, error)
}

Signer is used to sign tokens.

type Token

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

Token represents a JWT token. See: https://tools.ietf.org/html/rfc7519

func Parse

func Parse(raw []byte, verifier Verifier) (*Token, error)

Parse decodes a token and verifies it's signature.

Example
rawToken := []byte(`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0.dv9-XpY9P8ypm1uWQwB6eKvq3jeyodLA7brhjsf4JVs`)

key := []byte(`secret`)
verifier, _ := jwt.NewVerifierHS(jwt.HS256, key)

token, err := jwt.Parse(rawToken, verifier)
checkErr(err)

fmt.Printf("Algorithm %v\n", token.Header().Algorithm)
fmt.Printf("Type      %v\n", token.Header().Type)
fmt.Printf("Claims    %v\n", string(token.Claims()))
fmt.Printf("Payload   %v\n", string(token.PayloadPart()))
fmt.Printf("Token     %v\n", string(token.Bytes()))
Output:

Algorithm HS256
Type      JWT
Claims    {"aud":"admin","jti":"random-unique-string"}
Payload   eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0
Token     eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0.dv9-XpY9P8ypm1uWQwB6eKvq3jeyodLA7brhjsf4JVs

func ParseNoVerify

func ParseNoVerify(raw []byte) (*Token, error)

ParseNoVerify decodes a token from a raw bytes. NOTE: Consider to use Parse with a verifier to verify token signature.

Example
rawToken := []byte(`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0.dv9-XpY9P8ypm1uWQwB6eKvq3jeyodLA7brhjsf4JVs`)

token, err := jwt.ParseNoVerify(rawToken)
checkErr(err)

fmt.Printf("Algorithm %v\n", token.Header().Algorithm)
fmt.Printf("Type      %v\n", token.Header().Type)
fmt.Printf("Claims    %v\n", string(token.Claims()))
fmt.Printf("Payload   %v\n", string(token.PayloadPart()))
fmt.Printf("Token     %v\n", string(token.Bytes()))
Output:

Algorithm HS256
Type      JWT
Claims    {"aud":"admin","jti":"random-unique-string"}
Payload   eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0
Token     eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImp0aSI6InJhbmRvbS11bmlxdWUtc3RyaW5nIn0.dv9-XpY9P8ypm1uWQwB6eKvq3jeyodLA7brhjsf4JVs

func (*Token) Bytes

func (t *Token) Bytes() []byte

func (*Token) Claims

func (t *Token) Claims() json.RawMessage

Claims returns token's claims.

func (*Token) ClaimsPart

func (t *Token) ClaimsPart() []byte

ClaimsPart returns token claims part.

func (*Token) DecodeClaims

func (t *Token) DecodeClaims(dst interface{}) error

DecodeClaims into a given parameter.

func (*Token) Header

func (t *Token) Header() Header

Header returns token's header.

func (*Token) HeaderPart

func (t *Token) HeaderPart() []byte

HeaderPart returns token header part.

func (*Token) PayloadPart

func (t *Token) PayloadPart() []byte

PayloadPart returns token payload part.

func (*Token) Signature

func (t *Token) Signature() []byte

Signature returns token's signature.

func (*Token) SignaturePart

func (t *Token) SignaturePart() []byte

SignaturePart returns token signature part.

func (*Token) String

func (t *Token) String() string

type Verifier

type Verifier interface {
	Algorithm() Algorithm
	Verify(token *Token) error
}

Verifier is used to verify tokens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL