jwt

package
v1.1.7-rc1 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2021 License: MIT Imports: 25 Imported by: 423

README

github.com/lestrrat-go/jwx/jwt Go Reference

Package jwt implements JSON Web Tokens as described in RFC7519.

  • Convenience methods for oft-used keys ("aud", "sub", "iss", etc)
  • Convenience functions to extract/parse from http.Request, http.Header, url.Values
  • Ability to Get/Set arbitrary keys
  • Conversion to and from JSON
  • Generate signed tokens
  • Verify signed tokens

SYNOPSIS

More examples are located in the examples directory (jwt_example_test.go)

Verify a signed JWT

  token, err := jwt.Parse(bytes.NewReader(payload), jwt.WithKeySet(keyset))
  if err != nil {
    fmt.Printf("failed to parse payload: %s\n", err)
  }

Token Usage

func ExampleJWT() {
  const aLongLongTimeAgo = 233431200

  t := jwt.New()
  t.Set(jwt.SubjectKey, `https://github.com/lestrrat-go/jwx/jwt`)
  t.Set(jwt.AudienceKey, `Golang Users`)
  t.Set(jwt.IssuedAtKey, time.Unix(aLongLongTimeAgo, 0))
  t.Set(`privateClaimKey`, `Hello, World!`)

  buf, err := json.MarshalIndent(t, "", "  ")
  if err != nil {
    fmt.Printf("failed to generate JSON: %s\n", err)
    return
  }

  fmt.Printf("%s\n", buf)
  fmt.Printf("aud -> '%s'\n", t.Audience())
  fmt.Printf("iat -> '%s'\n", t.IssuedAt().Format(time.RFC3339))
  if v, ok := t.Get(`privateClaimKey`); ok {
    fmt.Printf("privateClaimKey -> '%s'\n", v)
  }
  fmt.Printf("sub -> '%s'\n", t.Subject())

  key, err := rsa.GenerateKey(rand.Reader, 2048)
  if err != nil {
    log.Printf("failed to generate private key: %s", err)
    return
  }

  {
    // Signing a token (using raw rsa.PrivateKey)
    signed, err := jwt.Sign(t, jwa.RS256, key)
    if err != nil {
      log.Printf("failed to sign token: %s", err)
      return
    }
    _ = signed
  }

  {
    // Signing a token (using JWK)
    jwkKey, err := jwk.New(key)
    if err != nil {
      log.Printf("failed to create JWK key: %s", err)
      return
    }

    signed, err := jwt.Sign(t, jwa.RS256, jwkKey)
    if err != nil {
      log.Printf("failed to sign token: %s", err)
      return
    }
    _ = signed
  }
}

OpenID Claims

jwt package can work with token types other than the default one. For OpenID claims, use the token created by openid.New(), or use the jwt.WithOpenIDClaims(). If you need to use other specialized claims, use jwt.WithToken() to specify the exact token type

func Example_openid() {
  const aLongLongTimeAgo = 233431200

  t := openid.New()
  t.Set(jwt.SubjectKey, `https://github.com/lestrrat-go/jwx/jwt`)
  t.Set(jwt.AudienceKey, `Golang Users`)
  t.Set(jwt.IssuedAtKey, time.Unix(aLongLongTimeAgo, 0))
  t.Set(`privateClaimKey`, `Hello, World!`)

  addr := openid.NewAddress()
  addr.Set(openid.AddressPostalCodeKey, `105-0011`)
  addr.Set(openid.AddressCountryKey, `日本`)
  addr.Set(openid.AddressRegionKey, `東京都`)
  addr.Set(openid.AddressLocalityKey, `港区`)
  addr.Set(openid.AddressStreetAddressKey, `芝公園 4-2-8`)
  t.Set(openid.AddressKey, addr)

  buf, err := json.MarshalIndent(t, "", "  ")
  if err != nil {
    fmt.Printf("failed to generate JSON: %s\n", err)
    return
  }
  fmt.Printf("%s\n", buf)

  t2, err := jwt.ParseBytes(buf, jwt.WithOpenIDClaims())
  if err != nil {
    fmt.Printf("failed to parse JSON: %s\n", err)
    return
  }
  if _, ok := t2.(openid.Token); !ok {
    fmt.Printf("using jwt.WithOpenIDClaims() creates an openid.Token instance")
    return
  }
}

Documentation

Overview

Package jwt implements JSON Web Tokens as described in https://tools.ietf.org/html/rfc7519

Index

Constants

View Source
const (
	AudienceKey   = "aud"
	ExpirationKey = "exp"
	IssuedAtKey   = "iat"
	IssuerKey     = "iss"
	JwtIDKey      = "jti"
	NotBeforeKey  = "nbf"
	SubjectKey    = "sub"
)

Variables

This section is empty.

Functions

func Equal added in v1.1.0

func Equal(t1, t2 Token) bool

Equal compares two JWT tokens. Do not use `reflect.Equal` or the like to compare tokens as they will also compare extra detail such as sync.Mutex objects used to control concurrent access.

The comparison for values is currently done using a simple equality ("=="), except for time.Time, which uses time.Equal after dropping the monotonic clock and truncating the values to 1 second accuracy.

if both t1 and t2 are nil, returns true

func RegisterCustomField added in v1.1.2

func RegisterCustomField(name string, object interface{})

RegisterCustomField allows users to specify that a private field be decoded as an instance of the specified type. This option has a global effect.

For example, suppose you have a custom field `x-birthday`, which you want to represent as a string formatted in RFC3339 in JSON, but want it back as `time.Time`.

In that case you would register a custom field as follows

jwt.RegisterCustomField(`x-birthday`, timeT)

Then `token.Get("x-birthday")` will still return an `interface{}`, but you can convert its type to `time.Time`

bdayif, _ := token.Get(`x-birthday`)
bday := bdayif.(time.Time)

func Sign added in v1.0.0

func Sign(t Token, alg jwa.SignatureAlgorithm, key interface{}, options ...Option) ([]byte, error)

Sign is a convenience function to create a signed JWT token serialized in compact form.

It accepts either a raw key (e.g. rsa.PrivateKey, ecdsa.PrivateKey, etc) or a jwk.Key, and the name of the algorithm that should be used to sign the token.

If the key is a jwk.Key and the key contains a key ID (`kid` field), then it is added to the protected header generated by the signature

The algorithm specified in the `alg` parameter must be able to support the type of key you provided, otherwise an error is returned.

The protected header will also automatically have the `typ` field set to the literal value `JWT`, unless you provide a custom value for it by jwt.WithHeaders option.

func Validate added in v1.0.6

func Validate(t Token, options ...ValidateOption) error

Validate makes sure that the essential claims stand.

See the various `WithXXX` functions for optional parameters that can control the behavior of this method.

Types

type ClaimPair added in v0.9.1

type ClaimPair = mapiter.Pair

type Clock

type Clock interface {
	Now() time.Time
}

type ClockFunc

type ClockFunc func() time.Time

func (ClockFunc) Now

func (f ClockFunc) Now() time.Time

type Iterator added in v1.0.0

type Iterator = mapiter.Iterator

type Option

type Option = option.Interface

type ParseOption added in v1.0.6

type ParseOption interface {
	ReadFileOption
	// contains filtered or unexported methods
}

ParseOption describes an Option that can be passed to `Parse()`. ParseOption also implements ReadFileOption, therefore it may be safely pass them to `jwt.ReadFile()`

func UseDefaultKey added in v1.0.6

func UseDefaultKey(value bool) ParseOption

UseDefaultKey is used in conjunction with the option WithKeySet to instruct the Parse method to default to the single key in a key set when no Key ID is included in the JWT. If the key set contains multiple keys then the behaviour is unchanged.

func WithHeaders added in v1.0.3

func WithHeaders(hdrs jws.Headers) ParseOption

WithHeaders is passed to `Sign()` method, to allow specifying arbitrary header values to be included in the header section of the jws message

func WithKeySet added in v1.0.3

func WithKeySet(set jwk.Set) ParseOption

WithKeySet forces the Parse method to verify the JWT message using one of the keys in the given key set. The key to be used is chosen by matching the Key ID of the JWT and the ID of the given keys.

func WithToken added in v1.0.0

func WithToken(t Token) ParseOption

WithToken specifies the token instance that is used when parsing JWT tokens.

func WithValidate added in v1.0.6

func WithValidate(b bool) ParseOption

WithValidate is passed to `Parse()` method to denote that the validation of the JWT token should be performed after a successful] parsing of the incoming payload.

func WithVerify

func WithVerify(alg jwa.SignatureAlgorithm, key interface{}) ParseOption

WithVerify forces the Parse method to verify the JWT message using the given key. XXX Should have been named something like WithVerificationKey

type ParseRequestOption added in v1.1.4

type ParseRequestOption interface {
	ParseOption
	// contains filtered or unexported methods
}

ParseRequestOption describes an Option that can be passed to `ParseRequest()`.

func WithFormKey added in v1.1.4

func WithFormKey(v string) ParseRequestOption

WithFormKey is used to specify header keys to search for tokens.

While the type system allows this option to be passed to jwt.Parse() directly, doing so will have no effect. Only use it for HTTP request parsing functions

func WithHeaderKey added in v1.1.4

func WithHeaderKey(v string) ParseRequestOption

WithHeaderKey is used to specify header keys to search for tokens.

While the type system allows this option to be passed to jwt.Parse() directly, doing so will have no effect. Only use it for HTTP request parsing functions

type ReadFileOption added in v1.1.0

type ReadFileOption interface {
	Option
	// contains filtered or unexported methods
}

ReadFileOption describes options that can be passed to ReadFile.

type Token

type Token interface {
	Audience() []string
	Expiration() time.Time
	IssuedAt() time.Time
	Issuer() string
	JwtID() string
	NotBefore() time.Time
	Subject() string
	PrivateClaims() map[string]interface{}
	Get(string) (interface{}, bool)
	Set(string, interface{}) error
	Remove(string) error
	Clone() (Token, error)
	Iterate(context.Context) Iterator
	Walk(context.Context, Visitor) error
	AsMap(context.Context) (map[string]interface{}, error)
}

Token represents a generic JWT token. which are type-aware (to an extent). Other claims may be accessed via the `Get`/`Set` methods but their types are not taken into consideration at all. If you have non-standard claims that you must frequently access, consider creating accessors functions like the following

func SetFoo(tok jwt.Token) error func GetFoo(tok jwt.Token) (*Customtyp, error)

Embedding jwt.Token into another struct is not recommended, becase jwt.Token needs to handle private claims, and this really does not work well when it is embedded in other structure

func New

func New() Token

New creates a standard token, with minimal knowledge of possible claims. Standard claims include"aud", "exp", "iat", "iss", "jti", "nbf" and "sub". Convenience accessors are provided for these standard claims

func Parse

func Parse(s []byte, options ...ParseOption) (Token, error)

Parse parses the JWT token payload and creates a new `jwt.Token` object. The token must be encoded in either JSON format or compact format.

If the token is signed and you want to verify the payload matches the signature, you must pass the jwt.WithVerify(alg, key) or jwt.WithKeySet(jwk.Set) option. If you do not specify these parameters, no verification will be performed.

If you also want to assert the validity of the JWT itself (i.e. expiration and such), use the `Validate()` function on the returned token, or pass the `WithValidate(true)` option. Validate options can also be passed to `Parse`

This function takes both ParseOption and ValidateOption types: ParseOptions control the parsing behavior, and ValidateOptions are passed to `Validate()` when `jwt.WithValidate` is specified.

func ParseForm added in v1.1.4

func ParseForm(values url.Values, name string, options ...ParseOption) (Token, error)

ParseForm parses a JWT stored in a url.Value.

func ParseHeader added in v1.1.4

func ParseHeader(hdr http.Header, name string, options ...ParseOption) (Token, error)

ParseHeader parses a JWT stored in a http.Header.

For the header "Authorization", it will strip the prefix "Bearer " and will treat the remaining value as a JWT.

func ParseReader added in v1.1.0

func ParseReader(src io.Reader, options ...ParseOption) (Token, error)

ParseReader calls Parse against an io.Reader

func ParseRequest added in v1.1.4

func ParseRequest(req *http.Request, options ...ParseOption) (Token, error)

ParseRequest searches a http.Request object for a JWT token.

Specifying WithHeaderKey() will tell it to search under a specific header key. Specifying WithFormKey() will tell it to search under a specific form field.

By default, "Authorization" header will be searched.

If WithHeaderKey() is used, you must explicitly re-enable searching for "Authorization" header.

# searches for "Authorization"
jwthttp.ParseRequest(req)

# searches for "x-my-token" ONLY.
jwthttp.ParseRequest(req, http.WithHeaderKey("x-my-token"))

# searches for "Authorization" AND "x-my-token"
jwthttp.ParseRequest(req, http.WithHeaderKey("Authorization"), http.WithHeaderKey("x-my-token"))

func ParseString

func ParseString(s string, options ...ParseOption) (Token, error)

ParseString calls Parse against a string

func ReadFile added in v1.1.0

func ReadFile(path string, options ...ReadFileOption) (Token, error)

type ValidateOption added in v1.0.6

type ValidateOption interface {
	ParseOption
	// contains filtered or unexported methods
}

ValidateOption describes an Option that can be passed to Validate(). ValidateOption also implements ParseOption, therefore it may be safely passed to `Parse()` (and thus `jwt.ReadFile()`)

func WithAcceptableSkew

func WithAcceptableSkew(dur time.Duration) ValidateOption

WithAcceptableSkew specifies the duration in which exp and nbf claims may differ by. This value should be positive

func WithAudience

func WithAudience(s string) ValidateOption

WithAudience specifies that expected audience value. `Validate()` will return true if one of the values in the `aud` element matches this value. If not specified, the value of issuer is not verified at all.

func WithClaimValue added in v0.9.2

func WithClaimValue(name string, v interface{}) ValidateOption

WithClaimValue specifies that expected any claim value.

func WithClock

func WithClock(c Clock) ValidateOption

WithClock specifies the `Clock` to be used when verifying claims exp and nbf.

func WithIssuer

func WithIssuer(s string) ValidateOption

WithIssuer specifies that expected issuer value. If not specified, the value of issuer is not verified at all.

func WithJwtID

func WithJwtID(s string) ValidateOption

WithJwtID specifies that expected jti value. If not specified, the value of jti is not verified at all.

func WithSubject

func WithSubject(s string) ValidateOption

WithSubject specifies that expected subject value. If not specified, the value of subject is not verified at all.

type VerifyParameters

type VerifyParameters interface {
	Algorithm() jwa.SignatureAlgorithm
	Key() interface{}
}

type Visitor added in v0.9.1

type Visitor = iter.MapVisitor

type VisitorFunc added in v1.0.0

type VisitorFunc iter.MapVisitorFunc

Directories

Path Synopsis
internal
Package openid provides a specialized token that provides utilities to work with OpenID JWT tokens.
Package openid provides a specialized token that provides utilities to work with OpenID JWT tokens.

Jump to

Keyboard shortcuts

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