Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove StandardClaims in favor of RegisteredClaims #235

Merged
merged 1 commit into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 0 additions & 96 deletions claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,102 +119,6 @@ func (c *RegisteredClaims) VerifyIssuer(cmp string, req bool) bool {
return verifyIss(c.Issuer, cmp, req)
}

// StandardClaims are a structured version of the JWT Claims Set, as referenced at
// https://datatracker.ietf.org/doc/html/rfc7519#section-4. They do not follow the
// specification exactly, since they were based on an earlier draft of the
// specification and not updated. The main difference is that they only
// support integer-based date fields and singular audiences. This might lead to
// incompatibilities with other JWT implementations. The use of this is discouraged, instead
// the newer RegisteredClaims struct should be used.
//
// Deprecated: Use RegisteredClaims instead for a forward-compatible way to access registered claims in a struct.
type StandardClaims struct {
Audience string `json:"aud,omitempty"`
ExpiresAt int64 `json:"exp,omitempty"`
Id string `json:"jti,omitempty"`
IssuedAt int64 `json:"iat,omitempty"`
Issuer string `json:"iss,omitempty"`
NotBefore int64 `json:"nbf,omitempty"`
Subject string `json:"sub,omitempty"`
}

// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
func (c StandardClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc().Unix()

// The claims below are optional, by default, so if they are set to the
// default value in Go, let's not fail the verification for them.
if !c.VerifyExpiresAt(now, false) {
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
vErr.Errors |= ValidationErrorExpired
}

if !c.VerifyIssuedAt(now, false) {
vErr.Inner = ErrTokenUsedBeforeIssued
vErr.Errors |= ValidationErrorIssuedAt
}

if !c.VerifyNotBefore(now, false) {
vErr.Inner = ErrTokenNotValidYet
vErr.Errors |= ValidationErrorNotValidYet
}

if vErr.valid() {
return nil
}

return vErr
}

// VerifyAudience compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
return verifyAud([]string{c.Audience}, cmp, req)
}

// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
// If req is false, it will return true, if exp is unset.
func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
if c.ExpiresAt == 0 {
return verifyExp(nil, time.Unix(cmp, 0), req)
}

t := time.Unix(c.ExpiresAt, 0)
return verifyExp(&t, time.Unix(cmp, 0), req)
}

// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
// If req is false, it will return true, if iat is unset.
func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
if c.IssuedAt == 0 {
return verifyIat(nil, time.Unix(cmp, 0), req)
}

t := time.Unix(c.IssuedAt, 0)
return verifyIat(&t, time.Unix(cmp, 0), req)
}

// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
// If req is false, it will return true, if nbf is unset.
func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
if c.NotBefore == 0 {
return verifyNbf(nil, time.Unix(cmp, 0), req)
}

t := time.Unix(c.NotBefore, 0)
return verifyNbf(&t, time.Unix(cmp, 0), req)
}

// VerifyIssuer compares the iss claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
return verifyIss(c.Issuer, cmp, req)
}

// ----- helpers

func verifyAud(aud []string, cmp string, required bool) bool {
Expand Down
23 changes: 3 additions & 20 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,19 +199,6 @@ var jwtTestData = []struct {
&jwt.Parser{UseJSONNumber: true},
jwt.SigningMethodRS256,
},
{
"Standard Claims",
"",
defaultKeyFunc,
&jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
},
true,
0,
nil,
&jwt.Parser{UseJSONNumber: true},
jwt.SigningMethodRS256,
},
{
"JSON Number - basic expired",
"", // autogen
Expand Down Expand Up @@ -360,8 +347,6 @@ func TestParser_Parse(t *testing.T) {
switch data.claims.(type) {
case jwt.MapClaims:
token, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc)
case *jwt.StandardClaims:
token, err = parser.ParseWithClaims(data.tokenString, &jwt.StandardClaims{}, data.keyfunc)
case *jwt.RegisteredClaims:
token, err = parser.ParseWithClaims(data.tokenString, &jwt.RegisteredClaims{}, data.keyfunc)
}
Expand Down Expand Up @@ -454,8 +439,6 @@ func TestParser_ParseUnverified(t *testing.T) {
switch data.claims.(type) {
case jwt.MapClaims:
token, _, err = parser.ParseUnverified(data.tokenString, jwt.MapClaims{})
case *jwt.StandardClaims:
token, _, err = parser.ParseUnverified(data.tokenString, &jwt.StandardClaims{})
case *jwt.RegisteredClaims:
token, _, err = parser.ParseUnverified(data.tokenString, &jwt.RegisteredClaims{})
}
Expand Down Expand Up @@ -605,9 +588,9 @@ func BenchmarkParseUnverified(b *testing.B) {
b.Run("map_claims", func(b *testing.B) {
benchmarkParsing(b, parser, data.tokenString, jwt.MapClaims{})
})
case *jwt.StandardClaims:
b.Run("standard_claims", func(b *testing.B) {
benchmarkParsing(b, parser, data.tokenString, &jwt.StandardClaims{})
case *jwt.RegisteredClaims:
b.Run("registered_claims", func(b *testing.B) {
benchmarkParsing(b, parser, data.tokenString, &jwt.RegisteredClaims{})
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestToken_SigningString(t1 *testing.T) {
"typ": "JWT",
"alg": jwt.SigningMethodHS256.Alg(),
},
Claims: jwt.StandardClaims{},
Claims: jwt.RegisteredClaims{},
Signature: "",
Valid: false,
},
Expand Down Expand Up @@ -67,7 +67,7 @@ func BenchmarkToken_SigningString(b *testing.B) {
"typ": "JWT",
"alg": jwt.SigningMethodHS256.Alg(),
},
Claims: jwt.StandardClaims{},
Claims: jwt.RegisteredClaims{},
}
b.Run("BenchmarkToken_SigningString", func(b *testing.B) {
b.ResetTimer()
Expand Down