From 6f4f904379a177fd76deda9e255306c36ccd441f Mon Sep 17 00:00:00 2001 From: Dave Grijalva Date: Thu, 8 Mar 2018 15:04:09 -0800 Subject: [PATCH] add options to ParseFromRequest --- VERSION_HISTORY.md | 2 ++ request/request.go | 58 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/VERSION_HISTORY.md b/VERSION_HISTORY.md index 14f7279..6370298 100644 --- a/VERSION_HISTORY.md +++ b/VERSION_HISTORY.md @@ -4,6 +4,8 @@ * Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation * HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. #### 3.1.0 diff --git a/request/request.go b/request/request.go index 1807b39..70525cf 100644 --- a/request/request.go +++ b/request/request.go @@ -9,16 +9,60 @@ import ( // This behaves the same as Parse, but accepts a request and an extractor // instead of a token string. The Extractor interface allows you to define // the logic for extracting a token. Several useful implementations are provided. -func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) { - return ParseFromRequestWithClaims(req, extractor, jwt.MapClaims{}, keyFunc) +// +// You can provide options to modify parsing behavior +func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc, options ...ParseFromRequestOption) (token *jwt.Token, err error) { + // Create basic parser struct + p := &fromRequestParser{req, extractor, nil, nil} + + // Handle options + for _, option := range options { + option(p) + } + + // Set defaults + if p.claims == nil { + p.claims = jwt.MapClaims{} + } + if p.parser == nil { + p.parser = &jwt.Parser{} + } + + // perform extract + tokenString, err := p.extractor.ExtractToken(req) + if err != nil { + return nil, err + } + + // perform parse + return p.parser.ParseWithClaims(tokenString, p.claims, keyFunc) } // ParseFromRequest but with custom Claims type +// DEPRECATED: use ParseFromRequest and the WithClaims option func ParseFromRequestWithClaims(req *http.Request, extractor Extractor, claims jwt.Claims, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) { - // Extract token from request - if tokStr, err := extractor.ExtractToken(req); err == nil { - return jwt.ParseWithClaims(tokStr, claims, keyFunc) - } else { - return nil, err + return ParseFromRequest(req, extractor, keyFunc, WithClaims(claims)) +} + +type fromRequestParser struct { + req *http.Request + extractor Extractor + claims jwt.Claims + parser *jwt.Parser +} + +type ParseFromRequestOption func(*fromRequestParser) + +// Parse with custom claims +func WithClaims(claims jwt.Claims) ParseFromRequestOption { + return func(p *fromRequestParser) { + p.claims = claims + } +} + +// Parse using a custom parser +func WithParser(parser *jwt.Parser) ParseFromRequestOption { + return func(p *fromRequestParser) { + p.parser = parser } }