diff --git a/map_claims.go b/map_claims.go index 014acb9..43c17a4 100644 --- a/map_claims.go +++ b/map_claims.go @@ -4,8 +4,8 @@ import ( "encoding/json" ) -// MapClaims is a claims type that uses the map[string]interface{} for JSON decoding. -// This is the default claims type if you don't supply one +// MapClaims is a claims type that uses the map[string]interface{} for JSON +// decoding. This is the default claims type if you don't supply one type MapClaims map[string]interface{} // GetExpirationTime implements the Claims interface. diff --git a/parser_option.go b/parser_option.go index 0442cdc..8d5917e 100644 --- a/parser_option.go +++ b/parser_option.go @@ -2,28 +2,32 @@ package jwt import "time" -// ParserOption is used to implement functional-style options that modify the behavior of the parser. To add -// new options, just create a function (ideally beginning with With or Without) that returns an anonymous function that -// takes a *Parser type as input and manipulates its configuration accordingly. +// ParserOption is used to implement functional-style options that modify the +// behavior of the parser. To add new options, just create a function (ideally +// beginning with With or Without) that returns an anonymous function that takes +// a *Parser type as input and manipulates its configuration accordingly. type ParserOption func(*Parser) -// WithValidMethods is an option to supply algorithm methods that the parser will check. Only those methods will be considered valid. -// It is heavily encouraged to use this option in order to prevent attacks such as https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. +// WithValidMethods is an option to supply algorithm methods that the parser +// will check. Only those methods will be considered valid. It is heavily +// encouraged to use this option in order to prevent attacks such as +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. func WithValidMethods(methods []string) ParserOption { return func(p *Parser) { p.validMethods = methods } } -// WithJSONNumber is an option to configure the underlying JSON parser with UseNumber +// WithJSONNumber is an option to configure the underlying JSON parser with +// UseNumber. func WithJSONNumber() ParserOption { return func(p *Parser) { p.useJSONNumber = true } } -// WithoutClaimsValidation is an option to disable claims validation. This option should only be used if you exactly know -// what you are doing. +// WithoutClaimsValidation is an option to disable claims validation. This +// option should only be used if you exactly know what you are doing. func WithoutClaimsValidation() ParserOption { return func(p *Parser) { p.skipClaimsValidation = true @@ -58,9 +62,10 @@ func WithIssuedAt() ParserOption { // the `aud` claim. Validation will fail if the audience is not listed in the // token or the `aud` claim is missing. // -// NOTE: While the `aud` claim is OPTIONAL is a JWT, the handling of it is +// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is // application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim. +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an audience is expected. func WithAudience(aud string) ParserOption { return func(p *Parser) { p.validator.expectedAud = aud @@ -71,9 +76,10 @@ func WithAudience(aud string) ParserOption { // `iss` claim. Validation will fail if a different issuer is specified in the // token or the `iss` claim is missing. // -// NOTE: While the `iss` claim is OPTIONAL is a JWT, the handling of it is +// NOTE: While the `iss` claim is OPTIONAL in a JWT, the handling of it is // application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim. +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an issuer is expected. func WithIssuer(iss string) ParserOption { return func(p *Parser) { p.validator.expectedIss = iss @@ -84,9 +90,10 @@ func WithIssuer(iss string) ParserOption { // `sub` claim. Validation will fail if a different subject is specified in the // token or the `sub` claim is missing. // -// NOTE: While the `sub` claim is OPTIONAL is a JWT, the handling of it is +// NOTE: While the `sub` claim is OPTIONAL in a JWT, the handling of it is // application-specific. Since this validation API is helping developers in -// writing secure application, we decided to REQUIRE the existence of the claim. +// writing secure application, we decided to REQUIRE the existence of the claim, +// if a subject is expected. func WithSubject(sub string) ParserOption { return func(p *Parser) { p.validator.expectedSub = sub diff --git a/token.go b/token.go index d9e5d56..b345942 100644 --- a/token.go +++ b/token.go @@ -6,42 +6,49 @@ import ( "strings" ) -// DecodePaddingAllowed will switch the codec used for decoding JWTs respectively. Note that the JWS RFC7515 -// states that the tokens will utilize a Base64url encoding with no padding. Unfortunately, some implementations -// of JWT are producing non-standard tokens, and thus require support for decoding. Note that this is a global -// variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe. -// To use the non-recommended decoding, set this boolean to `true` prior to using this package. +// DecodePaddingAllowed will switch the codec used for decoding JWTs +// respectively. Note that the JWS RFC7515 states that the tokens will utilize a +// Base64url encoding with no padding. Unfortunately, some implementations of +// JWT are producing non-standard tokens, and thus require support for decoding. +// Note that this is a global variable, and updating it will change the behavior +// on a package level, and is also NOT go-routine safe. To use the +// non-recommended decoding, set this boolean to `true` prior to using this +// package. var DecodePaddingAllowed bool // DecodeStrict will switch the codec used for decoding JWTs into strict mode. -// In this mode, the decoder requires that trailing padding bits are zero, as described in RFC 4648 section 3.5. -// Note that this is a global variable, and updating it will change the behavior on a package level, and is also NOT go-routine safe. -// To use strict decoding, set this boolean to `true` prior to using this package. +// In this mode, the decoder requires that trailing padding bits are zero, as +// described in RFC 4648 section 3.5. Note that this is a global variable, and +// updating it will change the behavior on a package level, and is also NOT +// go-routine safe. To use strict decoding, set this boolean to `true` prior to +// using this package. var DecodeStrict bool // Keyfunc will be used by the Parse methods as a callback function to supply -// the key for verification. The function receives the parsed, -// but unverified Token. This allows you to use properties in the -// Header of the token (such as `kid`) to identify which key to use. +// the key for verification. The function receives the parsed, but unverified +// Token. This allows you to use properties in the Header of the token (such as +// `kid`) to identify which key to use. type Keyfunc func(*Token) (interface{}, error) -// Token represents a JWT Token. Different fields will be used depending on whether you're -// creating or parsing/verifying a token. +// Token represents a JWT Token. Different fields will be used depending on +// whether you're creating or parsing/verifying a token. type Token struct { - Raw string // The raw token. Populated when you Parse a token - Method SigningMethod // The signing method used or to be used - Header map[string]interface{} // The first segment of the token - Claims Claims // The second segment of the token - Signature string // The third segment of the token. Populated when you Parse a token - Valid bool // Is the token valid? Populated when you Parse/Verify a token + Raw string // Raw contains the raw token. Populated when you [Parse] a token + Method SigningMethod // Method is the signing method used or to be used + Header map[string]interface{} // Header is the first segment of the token + Claims Claims // Claims is the second segment of the token + Signature string // Signature is the third segment of the token. Populated when you Parse a token + Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token } -// New creates a new Token with the specified signing method and an empty map of claims. +// New creates a new [Token] with the specified signing method and an empty map of +// claims. func New(method SigningMethod) *Token { return NewWithClaims(method, MapClaims{}) } -// NewWithClaims creates a new Token with the specified signing method and claims. +// NewWithClaims creates a new [Token] with the specified signing method and +// claims. func NewWithClaims(method SigningMethod, claims Claims) *Token { return &Token{ Header: map[string]interface{}{ @@ -53,8 +60,8 @@ func NewWithClaims(method SigningMethod, claims Claims) *Token { } } -// SignedString creates and returns a complete, signed JWT. -// The token is signed using the SigningMethod specified in the token. +// SignedString creates and returns a complete, signed JWT. The token is signed +// using the SigningMethod specified in the token. func (t *Token) SignedString(key interface{}) (string, error) { var sig, sstr string var err error @@ -67,10 +74,9 @@ func (t *Token) SignedString(key interface{}) (string, error) { return strings.Join([]string{sstr, sig}, "."), nil } -// SigningString generates the signing string. This is the -// most expensive part of the whole deal. Unless you -// need this for something special, just go straight for -// the SignedString. +// SigningString generates the signing string. This is the most expensive part +// of the whole deal. Unless you need this for something special, just go +// straight for the SignedString. func (t *Token) SigningString() (string, error) { var err error var jsonValue []byte @@ -90,36 +96,38 @@ func (t *Token) SigningString() (string, error) { // Parse parses, validates, verifies the signature and returns the parsed token. // keyFunc will receive the parsed token and should return the cryptographic key -// for verifying the signature. -// The caller is strongly encouraged to set the WithValidMethods option to -// validate the 'alg' claim in the token matches the expected algorithm. -// For more details about the importance of validating the 'alg' claim, -// see https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ +// for verifying the signature. The caller is strongly encouraged to set the +// WithValidMethods option to validate the 'alg' claim in the token matches the +// expected algorithm. For more details about the importance of validating the +// 'alg' claim, see +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { return NewParser(options...).Parse(tokenString, keyFunc) } // ParseWithClaims is a shortcut for NewParser().ParseWithClaims(). // -// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims), -// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the -// proper memory for it before passing in the overall claims, otherwise you might run into a panic. +// Note: If you provide a custom claim implementation that embeds one of the +// standard claims (such as RegisteredClaims), make sure that a) you either +// embed a non-pointer version of the claims or b) if you are using a pointer, +// allocate the proper memory for it before passing in the overall claims, +// otherwise you might run into a panic. func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) } // EncodeSegment encodes a JWT specific base64url encoding with padding stripped // -// Deprecated: In a future release, we will demote this function to a non-exported function, since it -// should only be used internally +// Deprecated: In a future release, we will demote this function to a +// non-exported function, since it should only be used internally func EncodeSegment(seg []byte) string { return base64.RawURLEncoding.EncodeToString(seg) } // DecodeSegment decodes a JWT specific base64url encoding with padding stripped // -// Deprecated: In a future release, we will demote this function to a non-exported function, since it -// should only be used internally +// Deprecated: In a future release, we will demote this function to a +// non-exported function, since it should only be used internally func DecodeSegment(seg string) ([]byte, error) { encoding := base64.RawURLEncoding diff --git a/types.go b/types.go index ac8e140..b82b388 100644 --- a/types.go +++ b/types.go @@ -9,22 +9,23 @@ import ( "time" ) -// TimePrecision sets the precision of times and dates within this library. -// This has an influence on the precision of times when comparing expiry or -// other related time fields. Furthermore, it is also the precision of times -// when serializing. +// TimePrecision sets the precision of times and dates within this library. This +// has an influence on the precision of times when comparing expiry or other +// related time fields. Furthermore, it is also the precision of times when +// serializing. // // For backwards compatibility the default precision is set to seconds, so that // no fractional timestamps are generated. var TimePrecision = time.Second -// MarshalSingleStringAsArray modifies the behaviour of the ClaimStrings type, especially -// its MarshalJSON function. +// MarshalSingleStringAsArray modifies the behavior of the ClaimStrings type, +// especially its MarshalJSON function. // // If it is set to true (the default), it will always serialize the type as an -// array of strings, even if it just contains one element, defaulting to the behaviour -// of the underlying []string. If it is set to false, it will serialize to a single -// string, if it contains one element. Otherwise, it will serialize to an array of strings. +// array of strings, even if it just contains one element, defaulting to the +// behavior of the underlying []string. If it is set to false, it will serialize +// to a single string, if it contains one element. Otherwise, it will serialize +// to an array of strings. var MarshalSingleStringAsArray = true // NumericDate represents a JSON numeric date value, as referenced at @@ -58,9 +59,10 @@ func (date NumericDate) MarshalJSON() (b []byte, err error) { // For very large timestamps, UnixNano would overflow an int64, but this // function requires nanosecond level precision, so we have to use the // following technique to get round the issue: + // // 1. Take the normal unix timestamp to form the whole number part of the // output, - // 2. Take the result of the Nanosecond function, which retuns the offset + // 2. Take the result of the Nanosecond function, which returns the offset // within the second of the particular unix time instance, to form the // decimal part of the output // 3. Concatenate them to produce the final result @@ -72,9 +74,10 @@ func (date NumericDate) MarshalJSON() (b []byte, err error) { return output, nil } -// UnmarshalJSON is an implementation of the json.RawMessage interface and deserializses a -// NumericDate from a JSON representation, i.e. a json.Number. This number represents an UNIX epoch -// with either integer or non-integer seconds. +// UnmarshalJSON is an implementation of the json.RawMessage interface and +// deserializes a [NumericDate] from a JSON representation, i.e. a +// [json.Number]. This number represents an UNIX epoch with either integer or +// non-integer seconds. func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { var ( number json.Number @@ -95,8 +98,9 @@ func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { return nil } -// ClaimStrings is basically just a slice of strings, but it can be either serialized from a string array or just a string. -// This type is necessary, since the "aud" claim can either be a single string or an array. +// ClaimStrings is basically just a slice of strings, but it can be either +// serialized from a string array or just a string. This type is necessary, +// since the "aud" claim can either be a single string or an array. type ClaimStrings []string func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { @@ -133,10 +137,11 @@ func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { } func (s ClaimStrings) MarshalJSON() (b []byte, err error) { - // This handles a special case in the JWT RFC. If the string array, e.g. used by the "aud" field, - // only contains one element, it MAY be serialized as a single string. This may or may not be - // desired based on the ecosystem of other JWT library used, so we make it configurable by the - // variable MarshalSingleStringAsArray. + // This handles a special case in the JWT RFC. If the string array, e.g. + // used by the "aud" field, only contains one element, it MAY be serialized + // as a single string. This may or may not be desired based on the ecosystem + // of other JWT library used, so we make it configurable by the variable + // MarshalSingleStringAsArray. if len(s) == 1 && !MarshalSingleStringAsArray { return json.Marshal(s[0]) } diff --git a/validator.go b/validator.go index 5146965..fa724c2 100644 --- a/validator.go +++ b/validator.go @@ -9,7 +9,8 @@ import ( // a [Parser] during parsing and can be modified with various parser options. // // Note: This struct is intentionally not exported (yet) as we want to -// internally finalize its API. In the future, we might make it publicly available. +// internally finalize its API. In the future, we might make it publicly +// available. type validator struct { // leeway is an optional leeway that can be provided to account for clock skew. leeway time.Duration