From fb52ae4a3009a42fb126dbbffaccc1bec803c2d8 Mon Sep 17 00:00:00 2001 From: ston1th Date: Thu, 13 Sep 2018 14:18:11 +0200 Subject: [PATCH] added benchmarks --- claims.go | 9 +++++ jwt.go | 22 +++++------ jwt_test.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++------ token.go | 13 ++----- 4 files changed, 113 insertions(+), 34 deletions(-) diff --git a/claims.go b/claims.go index b0c99c9..10cbcfe 100644 --- a/claims.go +++ b/claims.go @@ -76,3 +76,12 @@ func (c Claims) Set(key string, v interface{}) { func (c Claims) Delete(key string) { delete(c, key) } + +// Copy returns a new Claims map +func (c Claims) Copy() (n Claims) { + n = make(Claims) + for k, v := range c { + n[k] = v + } + return +} diff --git a/jwt.go b/jwt.go index 4c52a10..e586aa3 100644 --- a/jwt.go +++ b/jwt.go @@ -10,7 +10,6 @@ import ( "encoding/json" "errors" "io" - "strings" "sync" "time" ) @@ -125,11 +124,10 @@ func (jwt *JWT) Invalidate(t *Token) error { if err := jwt.blacklisted(t.Sig()); err != nil { return err } - header := t.Header() - if header.GetString(TypClaim) != Typ { + if t.Header.GetString(TypClaim) != Typ { return ErrNoJWT } - h := ParseHash(header.GetString(AlgClaim)) + h := ParseHash(t.Header.GetString(AlgClaim)) if h == nil { return ErrUnsupportedAlg } @@ -185,11 +183,10 @@ func (jwt *JWT) Sign(t *Token) (err error) { if t == nil { return ErrTokenIsNil } - header := t.Header() - if header.GetString(TypClaim) != Typ { + if t.Header.GetString(TypClaim) != Typ { return ErrNoJWT } - h := ParseHash(header.GetString(AlgClaim)) + h := ParseHash(t.Header.GetString(AlgClaim)) if h == nil { return ErrUnsupportedAlg } @@ -200,7 +197,7 @@ func (jwt *JWT) Sign(t *Token) (err error) { if _, ok := t.Claims.Get(NbfClaim); !ok { t.Claims.Set(NbfClaim, now.Unix()) } - head, err := json.Marshal(header) + head, err := json.Marshal(t.Header) if err != nil { return } @@ -208,10 +205,10 @@ func (jwt *JWT) Sign(t *Token) (err error) { if err != nil { return } - t.data = strings.Join([]string{base64.URLEncoding.EncodeToString(head), base64.URLEncoding.EncodeToString(claims)}, TokenSeparator) + t.data = base64.URLEncoding.EncodeToString(head) + TokenSeparator + base64.URLEncoding.EncodeToString(claims) t.rawSignature = jwt.sum(t.data, h) t.signature = base64.URLEncoding.EncodeToString(t.rawSignature) - t.raw = strings.Join([]string{t.data, t.signature}, TokenSeparator) + t.raw = t.data + TokenSeparator + t.signature return } @@ -226,11 +223,10 @@ func (jwt *JWT) Verify(t *Token) error { } } now := time.Now().UTC().Unix() - header := t.Header() - if header.GetString(TypClaim) != Typ { + if t.Header.GetString(TypClaim) != Typ { return ErrNoJWT } - h := ParseHash(header.GetString(AlgClaim)) + h := ParseHash(t.Header.GetString(AlgClaim)) if h == nil { return ErrUnsupportedAlg } diff --git a/jwt_test.go b/jwt_test.go index 02c7eeb..59789d3 100644 --- a/jwt_test.go +++ b/jwt_test.go @@ -9,17 +9,19 @@ import ( "time" ) +var claims = Claims{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "fizz": "buzz", +} + func TestValidate(t *testing.T) { jwt, err := New(time.Second, NewMemBlacklist(), nil) if err != nil { t.Error(err) } - token := NewToken(Claims{ - "sub": "1234567890", - "name": "John Doe", - "admin": true, - "fizz": "buzz", - }, nil) + token := NewToken(claims.Copy(), nil) err = jwt.Sign(token) if err != nil { t.Error(err) @@ -86,12 +88,7 @@ func TestNoBlacklist(t *testing.T) { if err != nil { t.Error(err) } - token := NewToken(Claims{ - "sub": "1234567890", - "name": "John Doe", - "admin": true, - "fizz": "buzz", - }, nil) + token := NewToken(claims.Copy(), nil) err = jwt.Sign(token) if err != nil { t.Error(err) @@ -133,3 +130,85 @@ func TestInvalidSecretReader(t *testing.T) { t.Error(errors.New("error should be invalid key size")) } } + +func BenchmarkDecodeToken(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), nil) + jwt.Sign(t) + token := t.String() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + DecodeToken(token) + } +} + +func BenchmarkNew(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + New(0, nil, nil) + } +} + +func BenchmarkNewWithBlacklist(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + New(0, NewMemBlacklist(), nil) + } +} + +func BenchmarkSignHS256(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), nil) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Sign(t) + } +} + +func BenchmarkSignHS384(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), NewHS384()) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Sign(t) + } +} + +func BenchmarkSignHS512(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), NewHS512()) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Sign(t) + } +} + +func BenchmarkVerifyHS256(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), nil) + jwt.Sign(t) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Verify(t) + } +} + +func BenchmarkVerifyHS384(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), NewHS384()) + jwt.Sign(t) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Verify(t) + } +} + +func BenchmarkVerifyHS512(b *testing.B) { + jwt, _ := New(0, nil, nil) + t := NewToken(claims.Copy(), NewHS512()) + jwt.Sign(t) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + jwt.Verify(t) + } +} diff --git a/token.go b/token.go index b7e0b89..34760a3 100644 --- a/token.go +++ b/token.go @@ -14,7 +14,7 @@ type Token struct { data string signature string rawSignature []byte - header Claims + Header Claims Claims Claims } @@ -33,11 +33,6 @@ func (t *Token) RawSig() []byte { return t.rawSignature } -// Header returns the Tokens header -func (t *Token) Header() Claims { - return t.header -} - // Data returns the first two token fields func (t *Token) Data() string { return t.data @@ -54,7 +49,7 @@ func NewToken(claims Claims, hash Hash) *Token { hash = NewHS256() } return &Token{ - header: Claims{ + Header: Claims{ AlgClaim: hash.Alg(), TypClaim: Typ, }, @@ -84,7 +79,7 @@ func DecodeToken(token string) (t *Token, err error) { if err != nil { return } - err = json.Unmarshal(header, &t.header) + err = json.Unmarshal(header, &t.Header) if err != nil { return } @@ -98,7 +93,7 @@ func DecodeToken(token string) (t *Token, err error) { } t.rawSignature, err = base64.URLEncoding.DecodeString(parts[2]) t.signature = parts[2] - t.data = strings.Join(parts[:2], TokenSeparator) + t.data = parts[0] + TokenSeparator + parts[1] t.raw = token return }