Source File
validator.go
Belonging Package
github.com/golang-jwt/jwt/v5
package jwtimport ()// ClaimsValidator is an interface that can be implemented by custom claims who// wish to execute any additional claims validation based on// application-specific logic. The Validate function is then executed in// addition to the regular claims validation and any error returned is appended// to the final validation result.//// type MyCustomClaims struct {// Foo string `json:"foo"`// jwt.RegisteredClaims// }//// func (m MyCustomClaims) Validate() error {// if m.Foo != "bar" {// return errors.New("must be foobar")// }// return nil// }type ClaimsValidator interface {ClaimsValidate() error}// Validator is the core of the new Validation API. It is automatically used by// a [Parser] during parsing and can be modified with various parser options.//// The [NewValidator] function should be used to create an instance of this// struct.type Validator struct {// leeway is an optional leeway that can be provided to account for clock skew.leeway time.Duration// timeFunc is used to supply the current time that is needed for// validation. If unspecified, this defaults to time.Now.timeFunc func() time.Time// requireExp specifies whether the exp claim is requiredrequireExp bool// verifyIat specifies whether the iat (Issued At) claim will be verified.// According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this// only specifies the age of the token, but no validation check is// necessary. However, if wanted, it can be checked if the iat is// unrealistic, i.e., in the future.verifyIat bool// expectedAud contains the audience this token expects. Supplying an empty// string will disable aud checking.expectedAud string// expectedIss contains the issuer this token expects. Supplying an empty// string will disable iss checking.expectedIss string// expectedSub contains the subject this token expects. Supplying an empty// string will disable sub checking.expectedSub string}// NewValidator can be used to create a stand-alone validator with the supplied// options. This validator can then be used to validate already parsed claims.//// Note: Under normal circumstances, explicitly creating a validator is not// needed and can potentially be dangerous; instead functions of the [Parser]// class should be used.//// The [Validator] is only checking the *validity* of the claims, such as its// expiration time, but it does NOT perform *signature verification* of the// token.func ( ...ParserOption) *Validator {:= NewParser(...)return .validator}// Validate validates the given claims. It will also perform any custom// validation if claims implements the [ClaimsValidator] interface.//// Note: It will NOT perform any *signature verification* on the token that// contains the claims and expects that the [Claim] was already successfully// verified.func ( *Validator) ( Claims) error {var (time.Time[]error = make([]error, 0, 6)error)// Check, if we have a time funcif .timeFunc != nil {= .timeFunc()} else {= time.Now()}// We always need to check the expiration time, but usage of the claim// itself is OPTIONAL by default. requireExp overrides this behavior// and makes the exp claim mandatory.if = .verifyExpiresAt(, , .requireExp); != nil {= append(, )}// We always need to check not-before, but usage of the claim itself is// OPTIONAL.if = .verifyNotBefore(, , false); != nil {= append(, )}// Check issued-at if the option is enabledif .verifyIat {if = .verifyIssuedAt(, , false); != nil {= append(, )}}// If we have an expected audience, we also require the audience claimif .expectedAud != "" {if = .verifyAudience(, .expectedAud, true); != nil {= append(, )}}// If we have an expected issuer, we also require the issuer claimif .expectedIss != "" {if = .verifyIssuer(, .expectedIss, true); != nil {= append(, )}}// If we have an expected subject, we also require the subject claimif .expectedSub != "" {if = .verifySubject(, .expectedSub, true); != nil {= append(, )}}// Finally, we want to give the claim itself some possibility to do some// additional custom validation based on a custom Validate function., := .(ClaimsValidator)if {if := .Validate(); != nil {= append(, )}}if len() == 0 {return nil}return joinErrors(...)}// verifyExpiresAt compares the exp claim in claims against cmp. This function// will succeed if cmp < exp. Additional leeway is taken into account.//// If exp is not set, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, time.Time, bool) error {, := .GetExpirationTime()if != nil {return}if == nil {return errorIfRequired(, "exp")}return errorIfFalse(.Before((.Time).Add(+.leeway)), ErrTokenExpired)}// verifyIssuedAt compares the iat claim in claims against cmp. This function// will succeed if cmp >= iat. Additional leeway is taken into account.//// If iat is not set, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, time.Time, bool) error {, := .GetIssuedAt()if != nil {return}if == nil {return errorIfRequired(, "iat")}return errorIfFalse(!.Before(.Add(-.leeway)), ErrTokenUsedBeforeIssued)}// verifyNotBefore compares the nbf claim in claims against cmp. This function// will return true if cmp >= nbf. Additional leeway is taken into account.//// If nbf is not set, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, time.Time, bool) error {, := .GetNotBefore()if != nil {return}if == nil {return errorIfRequired(, "nbf")}return errorIfFalse(!.Before(.Add(-.leeway)), ErrTokenNotValidYet)}// verifyAudience compares the aud claim against cmp.//// If aud is not set or an empty list, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, string, bool) error {, := .GetAudience()if != nil {return}if len() == 0 {return errorIfRequired(, "aud")}// use a var here to keep constant time compare when looping over a number of claims:= falsevar stringfor , := range {if subtle.ConstantTimeCompare([]byte(), []byte()) != 0 {= true}= +}// case where "" is sent in one or many aud claimsif == "" {return errorIfRequired(, "aud")}return errorIfFalse(, ErrTokenInvalidAudience)}// verifyIssuer compares the iss claim in claims against cmp.//// If iss is not set, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, string, bool) error {, := .GetIssuer()if != nil {return}if == "" {return errorIfRequired(, "iss")}return errorIfFalse( == , ErrTokenInvalidIssuer)}// verifySubject compares the sub claim against cmp.//// If sub is not set, it will succeed if the claim is not required,// otherwise ErrTokenRequiredClaimMissing will be returned.//// Additionally, if any error occurs while retrieving the claim, e.g., when its// the wrong type, an ErrTokenUnverifiable error will be returned.func ( *Validator) ( Claims, string, bool) error {, := .GetSubject()if != nil {return}if == "" {return errorIfRequired(, "sub")}return errorIfFalse( == , ErrTokenInvalidSubject)}// errorIfFalse returns the error specified in err, if the value is true.// Otherwise, nil is returned.func ( bool, error) error {if {return nil} else {return}}// errorIfRequired returns an ErrTokenRequiredClaimMissing error if required is// true. Otherwise, nil is returned.func ( bool, string) error {if {return newError(fmt.Sprintf("%s claim is required", ), ErrTokenRequiredClaimMissing)} else {return nil}}
![]() |
The pages are generated with Golds v0.7.6. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |