77 "strings"
88)
99
10- type Parser struct {
10+ type parserOpts struct {
1111 // If populated, only these methods will be considered valid.
1212 validMethods []string
1313
@@ -20,44 +20,54 @@ type Parser struct {
2020 validator * validator
2121}
2222
23+ type Parser [T Claims ] struct {
24+ opts parserOpts
25+ }
26+
2327// NewParser creates a new Parser with the specified options
24- func NewParser (options ... ParserOption ) * Parser {
25- p := & Parser {
26- validator : & validator {},
28+ func NewParser (options ... ParserOption ) * Parser [ MapClaims ] {
29+ p := & Parser [ MapClaims ] {
30+ opts : parserOpts { validator : & validator {} },
2731 }
2832
2933 // Loop through our parsing options and apply them
3034 for _ , option := range options {
31- option (p )
35+ option (& p . opts )
3236 }
3337
3438 return p
3539}
3640
37- // Parse parses, validates, verifies the signature and returns the parsed token.
38- // keyFunc will receive the parsed token and should return the key for validating.
39- func (p * Parser ) Parse (tokenString string , keyFunc Keyfunc ) (* Token , error ) {
40- return p .ParseWithClaims (tokenString , MapClaims {}, keyFunc )
41+ func NewParserFor [T Claims ](options ... ParserOption ) * Parser [T ] {
42+ p := & Parser [T ]{
43+ opts : parserOpts {validator : & validator {}},
44+ }
45+
46+ // Loop through our parsing options and apply them
47+ for _ , option := range options {
48+ option (& p .opts )
49+ }
50+
51+ return p
4152}
4253
43- // ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims
44- // interface. This provides default values which can be overridden and allows a caller to use their own type, rather
45- // than the default MapClaims implementation of Claims.
54+ // Parse parses, validates, verifies the signature and returns the parsed token.
55+ // keyFunc will receive the parsed token and should return the key for validating.
4656//
4757// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims),
4858// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the
4959// proper memory for it before passing in the overall claims, otherwise you might run into a panic.
50- func (p * Parser ) ParseWithClaims (tokenString string , claims Claims , keyFunc Keyfunc ) (* Token , error ) {
51- token , parts , err := p .ParseUnverified (tokenString , claims )
60+ func (p * Parser [ T ]) Parse (tokenString string , keyFunc Keyfunc [ T ] ) (* Token [ T ] , error ) {
61+ token , parts , err := p .ParseUnverified (tokenString )
5262 if err != nil {
5363 return token , err
5464 }
5565
5666 // Verify signing method is in the required set
57- if p .validMethods != nil {
58- var signingMethodValid = false
59- var alg = token .Method .Alg ()
60- for _ , m := range p .validMethods {
67+ if p .opts . validMethods != nil {
68+ signingMethodValid : = false
69+ alg : = token .Method .Alg ()
70+ for _ , m := range p .opts . validMethods {
6171 if m == alg {
6272 signingMethodValid = true
6373 break
@@ -86,13 +96,13 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
8696 }
8797
8898 // Validate Claims
89- if ! p .skipClaimsValidation {
99+ if ! p .opts . skipClaimsValidation {
90100 // Make sure we have at least a default validator
91- if p .validator == nil {
92- p .validator = newValidator ()
101+ if p .opts . validator == nil {
102+ p .opts . validator = newValidator ()
93103 }
94104
95- if err := p .validator .Validate (claims ); err != nil {
105+ if err := p .opts . validator .Validate (token . Claims ); err != nil {
96106 return token , newError ("" , ErrTokenInvalidClaims , err )
97107 }
98108 }
@@ -109,13 +119,13 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
109119//
110120// It's only ever useful in cases where you know the signature is valid (because it has
111121// been checked previously in the stack) and you want to extract values from it.
112- func (p * Parser ) ParseUnverified (tokenString string , claims Claims ) (token * Token , parts []string , err error ) {
122+ func (p * Parser [ T ] ) ParseUnverified (tokenString string ) (token * Token [ T ] , parts []string , err error ) {
113123 parts = strings .Split (tokenString , "." )
114124 if len (parts ) != 3 {
115125 return nil , parts , newError ("token contains an invalid number of segments" , ErrTokenMalformed )
116126 }
117127
118- token = & Token {Raw : tokenString }
128+ token = & Token [ T ] {Raw : tokenString }
119129
120130 // parse Header
121131 var headerBytes []byte
@@ -131,23 +141,17 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke
131141
132142 // parse Claims
133143 var claimBytes []byte
134- token .Claims = claims
135-
136144 if claimBytes , err = DecodeSegment (parts [1 ]); err != nil {
137145 return token , parts , newError ("could not base64 decode claim" , ErrTokenMalformed , err )
138146 }
147+
139148 dec := json .NewDecoder (bytes .NewBuffer (claimBytes ))
140- if p .useJSONNumber {
149+ if p .opts . useJSONNumber {
141150 dec .UseNumber ()
142151 }
143- // JSON Decode. Special case for map type to avoid weird pointer behavior
144- if c , ok := token .Claims .(MapClaims ); ok {
145- err = dec .Decode (& c )
146- } else {
147- err = dec .Decode (& claims )
148- }
152+
149153 // Handle decode error
150- if err != nil {
154+ if err = dec . Decode ( & token . Claims ); err != nil {
151155 return token , parts , newError ("could not JSON decode claim" , ErrTokenMalformed , err )
152156 }
153157
0 commit comments