...

Source file src/github.com/golang-jwt/jwt/v4/request/extractor.go

Documentation: github.com/golang-jwt/jwt/v4/request

     1  package request
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"strings"
     7  )
     8  
     9  // Errors
    10  var (
    11  	ErrNoTokenInRequest = errors.New("no token present in request")
    12  )
    13  
    14  // Extractor is an interface for extracting a token from an HTTP request.
    15  // The ExtractToken method should return a token string or an error.
    16  // If no token is present, you must return ErrNoTokenInRequest.
    17  type Extractor interface {
    18  	ExtractToken(*http.Request) (string, error)
    19  }
    20  
    21  // HeaderExtractor is an extractor for finding a token in a header.
    22  // Looks at each specified header in order until there's a match
    23  type HeaderExtractor []string
    24  
    25  func (e HeaderExtractor) ExtractToken(req *http.Request) (string, error) {
    26  	// loop over header names and return the first one that contains data
    27  	for _, header := range e {
    28  		if ah := req.Header.Get(header); ah != "" {
    29  			return ah, nil
    30  		}
    31  	}
    32  	return "", ErrNoTokenInRequest
    33  }
    34  
    35  // ArgumentExtractor extracts a token from request arguments.  This includes a POSTed form or
    36  // GET URL arguments.  Argument names are tried in order until there's a match.
    37  // This extractor calls `ParseMultipartForm` on the request
    38  type ArgumentExtractor []string
    39  
    40  func (e ArgumentExtractor) ExtractToken(req *http.Request) (string, error) {
    41  	// Make sure form is parsed
    42  	req.ParseMultipartForm(10e6)
    43  
    44  	// loop over arg names and return the first one that contains data
    45  	for _, arg := range e {
    46  		if ah := req.Form.Get(arg); ah != "" {
    47  			return ah, nil
    48  		}
    49  	}
    50  
    51  	return "", ErrNoTokenInRequest
    52  }
    53  
    54  // MultiExtractor tries Extractors in order until one returns a token string or an error occurs
    55  type MultiExtractor []Extractor
    56  
    57  func (e MultiExtractor) ExtractToken(req *http.Request) (string, error) {
    58  	// loop over header names and return the first one that contains data
    59  	for _, extractor := range e {
    60  		if tok, err := extractor.ExtractToken(req); tok != "" {
    61  			return tok, nil
    62  		} else if !errors.Is(err, ErrNoTokenInRequest) {
    63  			return "", err
    64  		}
    65  	}
    66  	return "", ErrNoTokenInRequest
    67  }
    68  
    69  // PostExtractionFilter wraps an Extractor in this to post-process the value before it's handed off.
    70  // See AuthorizationHeaderExtractor for an example
    71  type PostExtractionFilter struct {
    72  	Extractor
    73  	Filter func(string) (string, error)
    74  }
    75  
    76  func (e *PostExtractionFilter) ExtractToken(req *http.Request) (string, error) {
    77  	if tok, err := e.Extractor.ExtractToken(req); tok != "" {
    78  		return e.Filter(tok)
    79  	} else {
    80  		return "", err
    81  	}
    82  }
    83  
    84  // BearerExtractor extracts a token from the Authorization header.
    85  // The header is expected to match the format "Bearer XX", where "XX" is the
    86  // JWT token.
    87  type BearerExtractor struct{}
    88  
    89  func (e BearerExtractor) ExtractToken(req *http.Request) (string, error) {
    90  	tokenHeader := req.Header.Get("Authorization")
    91  	// The usual convention is for "Bearer" to be title-cased. However, there's no
    92  	// strict rule around this, and it's best to follow the robustness principle here.
    93  	if tokenHeader == "" || !strings.HasPrefix(strings.ToLower(tokenHeader), "bearer ") {
    94  		return "", ErrNoTokenInRequest
    95  	}
    96  	return tokenHeader[7:], nil
    97  }
    98  

View as plain text