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