1package request
2
3import (
4	"net/http"
5
6	"github.com/golang-jwt/jwt/v4"
7)
8
9// ParseFromRequest extracts and parses a JWT token from an HTTP request.
10// This behaves the same as Parse, but accepts a request and an extractor
11// instead of a token string.  The Extractor interface allows you to define
12// the logic for extracting a token.  Several useful implementations are provided.
13//
14// You can provide options to modify parsing behavior
15func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc, options ...ParseFromRequestOption) (token *jwt.Token, err error) {
16	// Create basic parser struct
17	p := &fromRequestParser{req, extractor, nil, nil}
18
19	// Handle options
20	for _, option := range options {
21		option(p)
22	}
23
24	// Set defaults
25	if p.claims == nil {
26		p.claims = jwt.MapClaims{}
27	}
28	if p.parser == nil {
29		p.parser = &jwt.Parser{}
30	}
31
32	// perform extract
33	tokenString, err := p.extractor.ExtractToken(req)
34	if err != nil {
35		return nil, err
36	}
37
38	// perform parse
39	return p.parser.ParseWithClaims(tokenString, p.claims, keyFunc)
40}
41
42// ParseFromRequestWithClaims is an alias for ParseFromRequest but with custom Claims type.
43//
44// Deprecated: use ParseFromRequest and the WithClaims option
45func ParseFromRequestWithClaims(req *http.Request, extractor Extractor, claims jwt.Claims, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) {
46	return ParseFromRequest(req, extractor, keyFunc, WithClaims(claims))
47}
48
49type fromRequestParser struct {
50	req       *http.Request
51	extractor Extractor
52	claims    jwt.Claims
53	parser    *jwt.Parser
54}
55
56type ParseFromRequestOption func(*fromRequestParser)
57
58// WithClaims parses with custom claims
59func WithClaims(claims jwt.Claims) ParseFromRequestOption {
60	return func(p *fromRequestParser) {
61		p.claims = claims
62	}
63}
64
65// WithParser parses using a custom parser
66func WithParser(parser *jwt.Parser) ParseFromRequestOption {
67	return func(p *fromRequestParser) {
68		p.parser = parser
69	}
70}
71