github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/jwt/claims.go (about) 1 package jwt 2 3 import ( 4 "encoding/json" 5 "errors" 6 7 "github.com/dgrijalva/jwt-go" 8 ) 9 10 // JanusClaims is the temporary solution for JWT claims validation with leeway support, 11 // should be removed as soon as github.com/dgrijalva/jwt-go 4.0 will be released with 12 // leeway support out of the box. This code is loosely based on the solution from 13 // https://github.com/dgrijalva/jwt-go/issues/131 14 type JanusClaims struct { 15 jwt.MapClaims 16 17 leeway int64 18 } 19 20 // NewJanusClaims instantiates new JanusClaims 21 func NewJanusClaims(leeway int64) *JanusClaims { 22 return &JanusClaims{MapClaims: jwt.MapClaims{}, leeway: leeway} 23 } 24 25 // UnmarshalJSON is Unmarshaler interface implementation for JanusClaims to unmarshal nested map claims correctly 26 func (c *JanusClaims) UnmarshalJSON(text []byte) error { 27 return json.Unmarshal(text, &c.MapClaims) 28 } 29 30 // Valid validates time based claims "exp, iat, nbf". 31 // As well, if any of the above claims are not in the token, it will still 32 // be considered a valid claim. 33 func (c *JanusClaims) Valid() error { 34 vErr := new(jwt.ValidationError) 35 now := jwt.TimeFunc().Unix() 36 37 if c.VerifyExpiresAt(now, false) == false { 38 vErr.Inner = errors.New("token is expired") 39 vErr.Errors |= jwt.ValidationErrorExpired 40 } 41 42 if c.VerifyIssuedAt(now, false) == false { 43 vErr.Inner = errors.New("token used before issued") 44 vErr.Errors |= jwt.ValidationErrorIssuedAt 45 } 46 47 if c.VerifyNotBefore(now, false) == false { 48 vErr.Inner = errors.New("token is not valid yet") 49 vErr.Errors |= jwt.ValidationErrorNotValidYet 50 } 51 52 if vErr.Errors == 0 { 53 return nil 54 } 55 56 return vErr 57 } 58 59 // VerifyExpiresAt overrides jwt.StandardClaims.VerifyExpiresAt() to use leeway for check 60 func (c *JanusClaims) VerifyExpiresAt(cmp int64, req bool) bool { 61 return c.MapClaims.VerifyExpiresAt(cmp-c.leeway, req) 62 } 63 64 // VerifyIssuedAt overrides jwt.StandardClaims.VerifyIssuedAt() to use leeway for check 65 func (c *JanusClaims) VerifyIssuedAt(cmp int64, req bool) bool { 66 return c.MapClaims.VerifyIssuedAt(cmp+c.leeway, req) 67 } 68 69 // VerifyNotBefore overrides jwt.StandardClaims.VerifyNotBefore() to use leeway for check 70 func (c *JanusClaims) VerifyNotBefore(cmp int64, req bool) bool { 71 return c.MapClaims.VerifyNotBefore(cmp+c.leeway, req) 72 }