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 vErr := & ValidationError {}
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 // If the Claims Valid returned an error, check if it is a validation error,
97107 // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
98108 if e , ok := err .(* ValidationError ); ! ok {
@@ -124,13 +134,13 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
124134//
125135// It's only ever useful in cases where you know the signature is valid (because it has
126136// been checked previously in the stack) and you want to extract values from it.
127- func (p * Parser ) ParseUnverified (tokenString string , claims Claims ) (token * Token , parts []string , err error ) {
137+ func (p * Parser [ T ] ) ParseUnverified (tokenString string ) (token * Token [ T ] , parts []string , err error ) {
128138 parts = strings .Split (tokenString , "." )
129139 if len (parts ) != 3 {
130140 return nil , parts , NewValidationError ("token contains an invalid number of segments" , ValidationErrorMalformed )
131141 }
132142
133- token = & Token {Raw : tokenString }
143+ token = & Token [ T ] {Raw : tokenString }
134144
135145 // parse Header
136146 var headerBytes []byte
@@ -146,23 +156,17 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke
146156
147157 // parse Claims
148158 var claimBytes []byte
149- token .Claims = claims
150-
151159 if claimBytes , err = DecodeSegment (parts [1 ]); err != nil {
152160 return token , parts , & ValidationError {Inner : err , Errors : ValidationErrorMalformed }
153161 }
162+
154163 dec := json .NewDecoder (bytes .NewBuffer (claimBytes ))
155- if p .useJSONNumber {
164+ if p .opts . useJSONNumber {
156165 dec .UseNumber ()
157166 }
158- // JSON Decode. Special case for map type to avoid weird pointer behavior
159- if c , ok := token .Claims .(MapClaims ); ok {
160- err = dec .Decode (& c )
161- } else {
162- err = dec .Decode (& claims )
163- }
167+
164168 // Handle decode error
165- if err != nil {
169+ if err = dec . Decode ( & token . Claims ); err != nil {
166170 return token , parts , & ValidationError {Inner : err , Errors : ValidationErrorMalformed }
167171 }
168172
0 commit comments