1 package jwt
2 3 import (
4 "errors"
5 )
6 7 // Error constants
8 var (
9 ErrInvalidKey = errors.New("key is invalid")
10 ErrInvalidKeyType = errors.New("key is of invalid type")
11 ErrHashUnavailable = errors.New("the requested hash function is unavailable")
12 13 ErrTokenMalformed = errors.New("token is malformed")
14 ErrTokenUnverifiable = errors.New("token is unverifiable")
15 ErrTokenSignatureInvalid = errors.New("token signature is invalid")
16 17 ErrTokenInvalidAudience = errors.New("token has invalid audience")
18 ErrTokenExpired = errors.New("token is expired")
19 ErrTokenUsedBeforeIssued = errors.New("token used before issued")
20 ErrTokenInvalidIssuer = errors.New("token has invalid issuer")
21 ErrTokenNotValidYet = errors.New("token is not valid yet")
22 ErrTokenInvalidId = errors.New("token has invalid id")
23 ErrTokenInvalidClaims = errors.New("token has invalid claims")
24 )
25 26 // The errors that might occur when parsing and validating a token
27 const (
28 ValidationErrorMalformed uint32 = 1 << iota // Token is malformed
29 ValidationErrorUnverifiable // Token could not be verified because of signing problems
30 ValidationErrorSignatureInvalid // Signature validation failed
31 32 // Standard Claim validation errors
33 ValidationErrorAudience // AUD validation failed
34 ValidationErrorExpired // EXP validation failed
35 ValidationErrorIssuedAt // IAT validation failed
36 ValidationErrorIssuer // ISS validation failed
37 ValidationErrorNotValidYet // NBF validation failed
38 ValidationErrorId // JTI validation failed
39 ValidationErrorClaimsInvalid // Generic claims validation error
40 )
41 42 // NewValidationError is a helper for constructing a ValidationError with a string error message
43 func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
44 return &ValidationError{
45 text: errorText,
46 Errors: errorFlags,
47 }
48 }
49 50 // ValidationError represents an error from Parse if token is not valid
51 type ValidationError struct {
52 Inner error // stores the error returned by external dependencies, i.e.: KeyFunc
53 Errors uint32 // bitfield. see ValidationError... constants
54 text string // errors that do not have a valid error just have text
55 }
56 57 // Error is the implementation of the err interface.
58 func (e ValidationError) Error() string {
59 if e.Inner != nil {
60 return e.Inner.Error()
61 } else if e.text != "" {
62 return e.text
63 } else {
64 return "token is invalid"
65 }
66 }
67 68 // Unwrap gives errors.Is and errors.As access to the inner error.
69 func (e *ValidationError) Unwrap() error {
70 return e.Inner
71 }
72 73 // No errors
74 func (e *ValidationError) valid() bool {
75 return e.Errors == 0
76 }
77 78 // Is checks if this ValidationError is of the supplied error. We are first checking for the exact error message
79 // by comparing the inner error message. If that fails, we compare using the error flags. This way we can use
80 // custom error messages (mainly for backwards compatability) and still leverage errors.Is using the global error variables.
81 func (e *ValidationError) Is(err error) bool {
82 // Check, if our inner error is a direct match
83 if errors.Is(errors.Unwrap(e), err) {
84 return true
85 }
86 87 // Otherwise, we need to match using our error flags
88 switch err {
89 case ErrTokenMalformed:
90 return e.Errors&ValidationErrorMalformed != 0
91 case ErrTokenUnverifiable:
92 return e.Errors&ValidationErrorUnverifiable != 0
93 case ErrTokenSignatureInvalid:
94 return e.Errors&ValidationErrorSignatureInvalid != 0
95 case ErrTokenInvalidAudience:
96 return e.Errors&ValidationErrorAudience != 0
97 case ErrTokenExpired:
98 return e.Errors&ValidationErrorExpired != 0
99 case ErrTokenUsedBeforeIssued:
100 return e.Errors&ValidationErrorIssuedAt != 0
101 case ErrTokenInvalidIssuer:
102 return e.Errors&ValidationErrorIssuer != 0
103 case ErrTokenNotValidYet:
104 return e.Errors&ValidationErrorNotValidYet != 0
105 case ErrTokenInvalidId:
106 return e.Errors&ValidationErrorId != 0
107 case ErrTokenInvalidClaims:
108 return e.Errors&ValidationErrorClaimsInvalid != 0
109 }
110 111 return false
112 }
113