-
Notifications
You must be signed in to change notification settings - Fork 19
/
jwt.go
82 lines (70 loc) · 2.72 KB
/
jwt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package jwt
import (
"bytes"
"encoding/json"
"os"
"reflect"
"time"
)
// Map is just a type alias, a shortcut of map[string]interface{}.
type Map = map[string]interface{}
// Clock is used to validate tokens expiration if the "exp" (expiration) exists in the payload.
// It can be overridden to use any other time value, useful for testing.
//
// Usage: now := Clock()
var Clock = time.Now
// CompareHeader is the function which compares and validates
// the decoded header against the defined signature algorithm.
// Defaults to a fast and simple implementation but it can be modified
// to support custom usage when third-party jwt signers signs the token
// (e.g. from a java spring application).
//
// This affects every token of the current program.
// Use the `VerifyWithHeaderValidator` function to implement per-token validation instead.
var CompareHeader HeaderValidator = compareHeader
// ReadFile can be used to customize the way the
// Must/Load Key function helpers are loading the filenames from.
// Example of usage: embedded key pairs.
// Defaults to the `os.ReadFile` which reads the file from the physical disk.
var ReadFile = os.ReadFile
// Marshal same as json.Marshal.
// This variable can be modified to enable custom encoder behavior
// for a signed payload.
var Marshal = func(v interface{}) ([]byte, error) {
if b, ok := v.([]byte); ok {
return b, nil
}
return json.Marshal(v)
}
// Unmarshal same as json.Unmarshal
// but with the Decoder unmarshals a number into an interface{} as a
// json.Number instead of as a float64.
// This is the function being called on `VerifiedToken.Claims` method.
// This variable can be modified to enable custom decoder behavior.
var Unmarshal = defaultUnmarshal
// UnmarshalWithRequired protects the custom fields of JWT claims
// based on the json:required tag e.g. `json:"name,required"`.
// It accepts a struct value to be validated later on.
// Returns ErrMissingKey if a required value is missing from the payload.
//
// Usage:
//
// Unmarshal = UnmarshalWithRequired
// [...]
// A Go struct like: UserClaims { Username string `json:"username,required" `}
// [...]
// And `Verify` as usual.
func UnmarshalWithRequired(payload []byte, dest interface{}) error {
if err := defaultUnmarshal(payload, dest); err != nil {
return err
}
return meetRequirements(reflect.ValueOf(dest))
}
func defaultUnmarshal(payload []byte, dest interface{}) error {
dec := json.NewDecoder(bytes.NewReader(payload))
dec.UseNumber() // fixes the issue of setting float64 instead of int64 on maps.
return dec.Decode(&dest)
}
// InjectFunc can be used to further modify the final token's body part.
// Look the `GCM` function for a real implementation of this type.
type InjectFunc func(plainPayload []byte) ([]byte, error)