package
1.2.30
Repository: https://github.com/lestrrat-go/jwx.git
Documentation: pkg.go.dev

# README

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
  • Extra support for OpenID tokens via github.com/lestrrat-go/jwx/jwt/openid

How-to style documentation can be found in the docs directory.

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

SYNOPSIS

Verify a signed JWT

  token, err := jwt.Parse(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.WithToken(openid.New()). 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.Parse(buf, jwt.WithToken(openid.New()))
  if err != nil {
    fmt.Printf("failed to parse JSON: %s\n", err)
    return
  }
  if _, ok := t2.(openid.Token); !ok {
    fmt.Printf("using jwt.WithToken(openid.New()) creates an openid.Token instance")
    return
  }
}

FAQ

Why is jwt.Token an interface?

In this package, jwt.Token is an interface. This is not an arbitrary choice: there are actual reason for the type being an interface.

We understand that if you are migrating from another library this may be a deal breaker, but we hope you can at least appreciate the fact that this was not done arbitrarily, and that there were real technical trade offs that were evaluated.

No uninitialized tokens

First and foremost, by making it an interface, you cannot use an uninitialized token:

var token1 jwt.Token // this is nil, you can't just start using this
if err := json.Unmarshal(data, &token1); err != nil { // so you can't do this
   ...
}

// But you _can_ do this, and we _want_ you to do this so the object is properly initialized
token2 = jwt.New()
if err := json.Unmarshal(data, &token2); err != nil { // actually, in practice you should use jwt.Parse()
   ....
}

But why does it need to be initialized?

There are several reasons, but one of the reasons is that I'm using a sync.Mutex to avoid races. We want this to be properly initialized.

The other reason is that we support custom claims out of the box. The map[string]interface{} container is initialized during new. This is important when checking for equality using reflect-y methods (akin to reflect.DeepEqual), because if you allowed zero values, you could end up with "empty" tokens, that actually differ. Consider the following:

// assume jwt.Token was s struct, not an interface
token1 := jwt.Token{ privateClaims: make(map[string]interface{}) }
token2 := jwt.Token{ privateClaims: nil }

These are semantically equivalent, but users would need to be aware of this difference when comparing values. By forcing the user to use a constructor, we can force a uniform empty state.

Standard way to store values

Unlike some other libraries, this library allows you to store standard claims and non-standard claims in the same token.

You want to store standard claims in a properly typed field, which we do for fields like "iss", "nbf", etc. But for non-standard claims, there is just no way of doing this, so we have to use a container like map[string]interface{}

This means that if you allow direct access to these fields via a struct, you will have two different ways to access the claims, which is confusing:

tok.Issuer = ...
tok.PrivateClaims["foo"] = ...

So we want to hide where this data is stored, and use a standard method like Set() and Get() to store all the values. At this point you are effectively going to hide the implementation detail from the user, so you end up with a struct like below, which is fundamentally not so different from providing just an interface{}:

type Token struct {
  // unexported fields
}

func (tok *Token) Set(...) { ... }

Use of pointers to store values

We wanted to differentiate the state between a claim being uninitialized, and a claim being initialized to empty.

So we use pointers to store values:

type stdToken struct {
  ....
  issuer *string // if nil, uninitialized. if &(""), initialized to empty
}

This is fine for us, but we doubt that this would be something users would want to do. This is a subtle difference, but cluttering up the API with slight variations of the same type (i.e. pointers vs non-pointers) seemed like a bad idea to us.

token.Issuer = &issuer // want to avoid this

token.Set(jwt.IssuerKey, "foobar") // so this is what we picked

This way users no longer need to care how the data is internally stored.

Allow more than one type of token through the same interface

dgrijalva/jwt-go does this in a different way, but we felt that it would be more intuitive for all tokens to follow a single interface so there is fewer type conversions required.

See the openid token for an example.

# Packages

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

# Functions

ClaimContainsString can be used to check if the claim called `name`, which is expected to be a list of strings, contains `value`.
ClaimValueIs creates a Validator that checks if the value of claim `name` matches `value`.
Equal compares two JWT tokens.
ErrInvalidIssuedAt returns the immutable error used when `iat` claim is not satisfied.
ErrTokenExpired returns the immutable error used when `exp` claim is not satisfied.
No description provided by the author
InferAlgorithmFromKey allows jwt.Parse to guess the signature algorithm passed to `jws.Verify()`, in case the key you provided does not have a proper `alg` header.
IsExpirationValid is one of the default validators that will be executed.
IsIssuedAtValid is one of the default validators that will be executed.
IsNbfValid is one of the default validators that will be executed.
IsRequired creates a Validator that checks if the required claim `name` exists in the token.
IsValidationError returns true if the error is a validation error.
MaxDeltaIs implements the logic behind `WithMaxDelta()` option.
MinDeltaIs implements the logic behind `WithMinDelta()` option.
New creates a standard token, with minimal knowledge of possible claims.
No description provided by the author
NewSerializer creates a new empty serializer.
No description provided by the author
Parse parses the JWT token payload and creates a new `jwt.Token` object.
ParseForm parses a JWT stored in a url.Value.
ParseHeader parses a JWT stored in a http.Header.
ParseReader calls Parse against an io.Reader.
ParseRequest searches a http.Request object for a JWT token.
ParseString calls Parse against a string.
No description provided by the author
RegisterCustomField allows users to specify that a private field be decoded as an instance of the specified type.
Settings controls global settings that are specific to JWTs.
No description provided by the author
No description provided by the author
Sign is a convenience function to create a signed JWT token serialized in compact form.
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.
Validate makes sure that the essential claims stand.
ValidationCtxClock returns the Clock object associated with the current validation context.
No description provided by the author
WithAcceptableSkew specifies the duration in which exp and nbf claims may differ by.
WithAudience specifies that expected audience value.
WithClaimValue specifies the expected value for a given claim.
WithClock specifies the `Clock` to be used when verifying claims exp and nbf.
WithContext allows you to specify a context.Context object to be used with `jwt.Validate()` option.
WithDecrypt allows users to specify parameters for decryption using `jwe.Decrypt`.
WithFetchBackoff specifies the `backoff.Policy` object that should be passed to `jws.VerifyAuto()`, which in turn will be passed to `jwk.Fetch()` This is a wrapper over `jws.WithFetchBackoff()` that can be passed to `jwt.Parse()`, and will be ignored if you spcify `jws.WithJWKSetFetcher()`.
WithFetchWhitelist specifies the `jwk.Whitelist` object that should be passed to `jws.VerifyAuto()`, which in turn will be passed to `jwk.Fetch()` This is a wrapper over `jws.WithFetchWhitelist()` that can be passed to `jwt.Parse()`, and will be ignored if you spcify `jws.WithJWKSetFetcher()`.
WithFlattenAudience specifies if the "aud" claim should be flattened to a single string upon the token being serialized to JSON.
WithFormKey is used to specify header keys to search for tokens.
WithHeaderKey is used to specify header keys to search for tokens.
WithHeaders is passed to `jwt.Sign()` function, to allow specifying arbitrary header values to be included in the header section of the jws message This option will be deprecated in the next major version.
WithHTTPClient specifies the `*http.Client` object that should be passed to `jws.VerifyAuto()`, which in turn will be passed to `jwk.Fetch()` This is a wrapper over `jws.WithHTTPClient()` that can be passed to `jwt.Parse()`, and will be ignored if you spcify `jws.WithJWKSetFetcher()`.
WithIssuer specifies that expected issuer value.
WithJweHeaders is passed to "jwt.Serializer".Encrypt() method to allow specifying arbitrary header values to be included in the protected header of the JWE message.
WithJWKSetFetcher specifies the `jws.JWKSetFetcher` object that should be passed to `jws.VerifyAuto()` This is a wrapper over `jws.WithJWKSetFetcher()` that can be passed to `jwt.Parse()`.
WithJwsHeaders is passed to `jwt.Sign()` function or "jwt.Serializer".Sign() method, to allow specifying arbitrary header values to be included in the header section of the JWE message.
WithJwtID specifies that expected jti value.
WithKeySet forces the Parse method to verify the JWT message using one of the keys in the given key set.
WithKeySetProvider allows users to specify an object to choose which jwk.Set to use for verification.
WithMaxDelta specifies that given two claims `c1` and `c2` that represent time, the difference in time.Duration must be less than equal to the value specified by `d`.
WithMinDelta is almost exactly the same as WithMaxDelta, but force validation to fail if the difference between time claims are less than dur.
WithPedantic enables pedantic mode for parsing JWTs.
WithRequiredClaim specifies that the claim identified the given name must exist in the token.
WithSubject specifies that expected subject value.
WithToken specifies the token instance that is used when parsing JWT tokens.
WithTypedClaim allows a private claim to be parsed into the object type of your choice.
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.
WithValidator validates the token with the given Validator.
WithVerify forces the Parse method to verify the JWT message using the given key.
WithVerifyAuto specifies that the JWS verification should be performed using `jws.VerifyAuto()`, which in turn attempts to verify the message using values that are stored within the JWS message.

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

Builder is a convenience wrapper around the New() constructor and the Set() methods to assign values to Token claims.
Serializer is a generic serializer for JWTs.

# Interfaces

No description provided by the author
No description provided by the author
EncryptOption describes an Option that can be passed to Encrypt() or (jwt.Serializer).Encrypt.
GlobalOption describes an Option that can be passed to `Settings()`.
KeySetProvider is an interface for objects that can choose the appropriate jwk.Set to be used when verifying JWTs.
ParseOption describes an Option that can be passed to `Parse()`.
ParseRequestOption describes an Option that can be passed to `ParseRequest()`.
ReadFileOption describes options that can be passed to ReadFile.
No description provided by the author
No description provided by the author
SignOption describes an Option that can be passed to Sign() or (jwt.Serializer).Sign.
Token represents a generic JWT token.
ValidateOption describes an Option that can be passed to Validate().
No description provided by the author
Validator describes interface to validate a Token.
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
KeySetProviderFunc is an implementation of KeySetProvider that is based on a function.
No description provided by the author
No description provided by the author
ValidatorFunc is a type of Validator that does not have any state, that is implemented as a function.
No description provided by the author
No description provided by the author