Skip to content

Commit d3f78a0

Browse files
committed
feat: add backward-compat alias types
1 parent 191c1a9 commit d3f78a0

File tree

10 files changed

+48
-36
lines changed

10 files changed

+48
-36
lines changed

cmd/jwt/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func verifyToken() error {
128128
}
129129

130130
// Parse the token. Load the key from command line option
131-
token, err := jwt.Parse(string(tokData), func(t *jwt.Token[jwt.MapClaims]) (interface{}, error) {
131+
token, err := jwt.Parse(string(tokData), func(t *jwt.TokenFor[jwt.MapClaims]) (interface{}, error) {
132132
if isNone() {
133133
return jwt.UnsafeAllowNoneSignatureType, nil
134134
}

example_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func ExampleParseWithClaims_customClaimsType() {
8080
jwt.RegisteredClaims
8181
}
8282

83-
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.Token[*MyCustomClaims]) (interface{}, error) {
83+
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.TokenFor[*MyCustomClaims]) (interface{}, error) {
8484
return []byte("AllYourBase"), nil
8585
})
8686

@@ -103,7 +103,7 @@ func ExampleParseWithClaims_validationOptions() {
103103
jwt.RegisteredClaims
104104
}
105105

106-
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.Token[*MyCustomClaims]) (interface{}, error) {
106+
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.TokenFor[*MyCustomClaims]) (interface{}, error) {
107107
return []byte("AllYourBase"), nil
108108
}, jwt.WithLeeway(5*time.Second))
109109

@@ -138,7 +138,7 @@ func (m MyCustomClaims) Validate() error {
138138
func ExampleParseWithClaims_customValidation() {
139139
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpc3MiOiJ0ZXN0IiwiYXVkIjoic2luZ2xlIn0.QAWg1vGvnqRuCFTMcPkjZljXHh8U3L_qUjszOtQbeaA"
140140

141-
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.Token[*MyCustomClaims]) (interface{}, error) {
141+
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.TokenFor[*MyCustomClaims]) (interface{}, error) {
142142
return []byte("AllYourBase"), nil
143143
}, jwt.WithLeeway(5*time.Second))
144144

@@ -156,7 +156,7 @@ func ExampleParse_errorChecking() {
156156
// Token from another example. This token is expired
157157
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"
158158

159-
token, err := jwt.Parse(tokenString, func(token *jwt.Token[jwt.MapClaims]) (interface{}, error) {
159+
token, err := jwt.Parse(tokenString, func(token *jwt.TokenFor[jwt.MapClaims]) (interface{}, error) {
160160
return []byte("AllYourBase"), nil
161161
})
162162

hmac_example_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func ExampleParse_hmac() {
4747
// useful if you use multiple keys for your application. The standard is to use 'kid' in the
4848
// head of the token to identify which key to use, but the parsed token (head and claims) is provided
4949
// to the callback, providing flexibility.
50-
token, err := jwt.Parse(tokenString, func(token *jwt.Token[jwt.MapClaims]) (interface{}, error) {
50+
token, err := jwt.Parse(tokenString, func(token *jwt.TokenFor[jwt.MapClaims]) (interface{}, error) {
5151
// Don't forget to validate the alg is what you expect:
5252
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
5353
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])

http_example_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func Example_getTokenViaHTTP() {
9999
tokenString := strings.TrimSpace(buf.String())
100100

101101
// Parse the token
102-
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.Token[*CustomClaimsExample]) (interface{}, error) {
102+
token, err := jwt.ParseWithClaims(tokenString, func(token *jwt.TokenFor[*CustomClaimsExample]) (interface{}, error) {
103103
// since we only use the one private key to sign the tokens,
104104
// we also only use its public counter part to verify
105105
return verifyKey, nil
@@ -191,7 +191,7 @@ func authHandler(w http.ResponseWriter, r *http.Request) {
191191
// only accessible with a valid token
192192
func restrictedHandler(w http.ResponseWriter, r *http.Request) {
193193
// Get token from request
194-
token, err := request.ParseFromRequest(r, request.OAuth2Extractor, func(token *jwt.Token[*CustomClaimsExample]) (interface{}, error) {
194+
token, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, func(token *jwt.TokenFor[*CustomClaimsExample]) (interface{}, error) {
195195
// since we only use the one private key to sign the tokens,
196196
// we also only use its public counter part to verify
197197
return verifyKey, nil

parser.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func NewParserFor[T Claims](options ...ParserOption) *Parser[T] {
5757
// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
5858
// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
5959
// proper memory for it before passing in the overall claims, otherwise you might run into a panic.
60-
func (p *Parser[T]) Parse(tokenString string, keyFunc Keyfunc[T]) (*Token[T], error) {
60+
func (p *Parser[T]) Parse(tokenString string, keyFunc KeyfuncFor[T]) (*TokenFor[T], error) {
6161
token, parts, err := p.ParseUnverified(tokenString)
6262
if err != nil {
6363
return token, err
@@ -119,13 +119,13 @@ func (p *Parser[T]) Parse(tokenString string, keyFunc Keyfunc[T]) (*Token[T], er
119119
//
120120
// It's only ever useful in cases where you know the signature is valid (because it has
121121
// been checked previously in the stack) and you want to extract values from it.
122-
func (p *Parser[T]) ParseUnverified(tokenString string) (token *Token[T], parts []string, err error) {
122+
func (p *Parser[T]) ParseUnverified(tokenString string) (token *TokenFor[T], parts []string, err error) {
123123
parts = strings.Split(tokenString, ".")
124124
if len(parts) != 3 {
125125
return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed)
126126
}
127127

128-
token = &Token[T]{Raw: tokenString}
128+
token = &TokenFor[T]{Raw: tokenString}
129129

130130
// parse Header
131131
var headerBytes []byte

parser_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,18 @@ const (
3535
keyFuncNil
3636
)
3737

38-
func getKeyFunc[T jwt.Claims](kind keyFuncKind) jwt.Keyfunc[T] {
38+
func getKeyFunc[T jwt.Claims](kind keyFuncKind) jwt.KeyfuncFor[T] {
3939
switch kind {
4040
case keyFuncDefault:
41-
return func(t *jwt.Token[T]) (interface{}, error) { return jwtTestDefaultKey, nil }
41+
return func(t *jwt.TokenFor[T]) (interface{}, error) { return jwtTestDefaultKey, nil }
4242
case keyFuncECDSA:
43-
return func(t *jwt.Token[T]) (interface{}, error) { return jwtTestEC256PublicKey, nil }
43+
return func(t *jwt.TokenFor[T]) (interface{}, error) { return jwtTestEC256PublicKey, nil }
4444
case keyFuncPadded:
45-
return func(t *jwt.Token[T]) (interface{}, error) { return paddedKey, nil }
45+
return func(t *jwt.TokenFor[T]) (interface{}, error) { return paddedKey, nil }
4646
case keyFuncEmpty:
47-
return func(t *jwt.Token[T]) (interface{}, error) { return nil, nil }
47+
return func(t *jwt.TokenFor[T]) (interface{}, error) { return nil, nil }
4848
case keyFuncError:
49-
return func(t *jwt.Token[T]) (interface{}, error) { return nil, errKeyFuncError }
49+
return func(t *jwt.TokenFor[T]) (interface{}, error) { return nil, errKeyFuncError }
5050
case keyFuncNil:
5151
return nil
5252
default:
@@ -376,8 +376,8 @@ func signToken(claims jwt.Claims, signingMethod jwt.SigningMethod) string {
376376

377377
// cloneToken is necesssary to "forget" the type information back to a generic jwt.Claims.
378378
// Assignment of parameterized types is currently (1.20) not supported.
379-
func cloneToken[T jwt.Claims](tin *jwt.Token[T]) *jwt.Token[jwt.Claims] {
380-
tout := &jwt.Token[jwt.Claims]{}
379+
func cloneToken[T jwt.Claims](tin *jwt.TokenFor[T]) *jwt.TokenFor[jwt.Claims] {
380+
tout := &jwt.TokenFor[jwt.Claims]{}
381381
tout.Claims = tin.Claims
382382
tout.Header = tin.Header
383383
tout.Method = tin.Method
@@ -397,7 +397,7 @@ func TestParser_Parse(t *testing.T) {
397397
}
398398

399399
// Parse the token
400-
var token *jwt.Token[jwt.Claims]
400+
var token *jwt.TokenFor[jwt.Claims]
401401
var err error
402402
switch data.claims.(type) {
403403
case jwt.MapClaims:
@@ -475,7 +475,7 @@ func TestParser_ParseUnverified(t *testing.T) {
475475
}
476476

477477
// Parse the token
478-
var token *jwt.Token[jwt.Claims]
478+
var token *jwt.TokenFor[jwt.Claims]
479479
var err error
480480
switch data.claims.(type) {
481481
case jwt.MapClaims:

request/request.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import (
1212
// the logic for extracting a token. Several useful implementations are provided.
1313
//
1414
// You can provide options to modify parsing behavior
15-
func ParseFromRequest[T jwt.Claims](req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc[T], options ...ParseFromRequestOption[T]) (token *jwt.Token[T], err error) {
15+
func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc, options ...Option) (token *jwt.Token, err error) {
16+
return ParseFromRequestWithClaims(req, extractor, keyFunc, options...)
17+
}
18+
19+
func ParseFromRequestWithClaims[T jwt.Claims](req *http.Request, extractor Extractor, keyFunc jwt.KeyfuncFor[T], options ...OptionFor[T]) (token *jwt.TokenFor[T], err error) {
1620
// Create basic parser struct
1721
p := &fromRequestParser[T]{
1822
req: req,
@@ -45,10 +49,12 @@ type fromRequestParser[T jwt.Claims] struct {
4549
parser *jwt.Parser[T]
4650
}
4751

48-
type ParseFromRequestOption[T jwt.Claims] func(*fromRequestParser[T])
52+
type OptionFor[T jwt.Claims] func(*fromRequestParser[T])
53+
54+
type Option = OptionFor[jwt.MapClaims]
4955

5056
// WithParser parses using a custom parser
51-
func WithParser[T jwt.Claims](parser *jwt.Parser[T]) ParseFromRequestOption[T] {
57+
func WithParser[T jwt.Claims](parser *jwt.Parser[T]) OptionFor[T] {
5258
return func(p *fromRequestParser[T]) {
5359
p.parser = parser
5460
}

request/request_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestParseRequest(t *testing.T) {
5858
// load keys from disk
5959
privateKey := test.LoadRSAPrivateKeyFromDisk("../test/sample_key")
6060
publicKey := test.LoadRSAPublicKeyFromDisk("../test/sample_key.pub")
61-
keyfunc := func(*jwt.Token[jwt.MapClaims]) (interface{}, error) {
61+
keyfunc := func(*jwt.TokenFor[jwt.MapClaims]) (interface{}, error) {
6262
return publicKey, nil
6363
}
6464

token.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ var DecodeStrict bool
2828
// the key for verification. The function receives the parsed, but unverified
2929
// Token. This allows you to use properties in the Header of the token (such as
3030
// `kid`) to identify which key to use.
31-
type Keyfunc[T Claims] func(*Token[T]) (interface{}, error)
31+
type KeyfuncFor[T Claims] func(*TokenFor[T]) (interface{}, error)
32+
33+
// Keyfunc is an alias for KeyfuncFor[Claims], for backward compatibility.
34+
type Keyfunc = KeyfuncFor[MapClaims]
3235

3336
// Token represents a JWT Token. Different fields will be used depending on
3437
// whether you're creating or parsing/verifying a token.
35-
type Token[T Claims] struct {
38+
type TokenFor[T Claims] struct {
3639
Raw string // Raw contains the raw token. Populated when you [Parse] a token
3740
Method SigningMethod // Method is the signing method used or to be used
3841
Header map[string]interface{} // Header is the first segment of the token
@@ -41,16 +44,19 @@ type Token[T Claims] struct {
4144
Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token
4245
}
4346

47+
// Token is an alias for TokenFor[Claims], for backward compatibility.
48+
type Token = TokenFor[MapClaims]
49+
4450
// New creates a new [Token] with the specified signing method and an empty map of
4551
// claims.
46-
func New(method SigningMethod) *Token[MapClaims] {
52+
func New(method SigningMethod) *Token {
4753
return NewWithClaims(method, MapClaims{})
4854
}
4955

5056
// NewWithClaims creates a new [Token] with the specified signing method and
5157
// claims.
52-
func NewWithClaims[T Claims](method SigningMethod, claims T) *Token[T] {
53-
return &Token[T]{
58+
func NewWithClaims[T Claims](method SigningMethod, claims T) *TokenFor[T] {
59+
return &TokenFor[T]{
5460
Header: map[string]interface{}{
5561
"typ": "JWT",
5662
"alg": method.Alg(),
@@ -62,7 +68,7 @@ func NewWithClaims[T Claims](method SigningMethod, claims T) *Token[T] {
6268

6369
// SignedString creates and returns a complete, signed JWT. The token is signed
6470
// using the SigningMethod specified in the token.
65-
func (t *Token[T]) SignedString(key interface{}) (string, error) {
71+
func (t *TokenFor[T]) SignedString(key interface{}) (string, error) {
6672
sstr, err := t.SigningString()
6773
if err != nil {
6874
return "", err
@@ -79,7 +85,7 @@ func (t *Token[T]) SignedString(key interface{}) (string, error) {
7985
// SigningString generates the signing string. This is the most expensive part
8086
// of the whole deal. Unless you need this for something special, just go
8187
// straight for the SignedString.
82-
func (t *Token[T]) SigningString() (string, error) {
88+
func (t *TokenFor[T]) SigningString() (string, error) {
8389
h, err := json.Marshal(t.Header)
8490
if err != nil {
8591
return "", err
@@ -100,7 +106,7 @@ func (t *Token[T]) SigningString() (string, error) {
100106
// expected algorithm. For more details about the importance of validating the
101107
// 'alg' claim, see
102108
// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
103-
func Parse(tokenString string, keyFunc Keyfunc[MapClaims], options ...ParserOption) (*Token[MapClaims], error) {
109+
func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
104110
return NewParser(options...).Parse(tokenString, keyFunc)
105111
}
106112

@@ -111,7 +117,7 @@ func Parse(tokenString string, keyFunc Keyfunc[MapClaims], options ...ParserOpti
111117
// embed a non-pointer version of the claims or b) if you are using a pointer,
112118
// allocate the proper memory for it before passing in the overall claims,
113119
// otherwise you might run into a panic.
114-
func ParseWithClaims[T Claims](tokenString string, keyFunc Keyfunc[T], options ...ParserOption) (*Token[T], error) {
120+
func ParseWithClaims[T Claims](tokenString string, keyFunc KeyfuncFor[T], options ...ParserOption) (*TokenFor[T], error) {
115121
return NewParserFor[T](options...).Parse(tokenString, keyFunc)
116122
}
117123

token_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func TestToken_SigningString(t1 *testing.T) {
4040
}
4141
for _, tt := range tests {
4242
t1.Run(tt.name, func(t1 *testing.T) {
43-
t := &jwt.Token[jwt.Claims]{
43+
t := &jwt.TokenFor[jwt.Claims]{
4444
Raw: tt.fields.Raw,
4545
Method: tt.fields.Method,
4646
Header: tt.fields.Header,
@@ -61,7 +61,7 @@ func TestToken_SigningString(t1 *testing.T) {
6161
}
6262

6363
func BenchmarkToken_SigningString(b *testing.B) {
64-
t := &jwt.Token[jwt.Claims]{
64+
t := &jwt.TokenFor[jwt.Claims]{
6565
Method: jwt.SigningMethodHS256,
6666
Header: map[string]interface{}{
6767
"typ": "JWT",

0 commit comments

Comments
 (0)