-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcustom.go
More file actions
117 lines (87 loc) · 2.68 KB
/
custom.go
File metadata and controls
117 lines (87 loc) · 2.68 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package jwt
import (
"bytes"
"crypto/hmac"
"encoding/base64"
)
type ValidatorFunction func(claims interface{}) bool
func NewWithCustom(key []byte, algo *Algorithm, claims interface{}) ([]byte, error) {
var message []byte
header := acquireHeader()
defer releaseHeader(header)
header.Algorithm = algo.Name
encodedHeader, err := header.Encode()
if err != nil {
return nil, err
}
message = append(message, encodedHeader...)
encodedClaims, err := encodeCustomClaims(claims)
if err != nil {
return nil, err
}
message = append(message, dot...)
message = append(message, encodedClaims...)
mac := hmac.New(algo.Hash, key)
_, err = mac.Write(message)
if err != nil {
return nil, err
}
message = append(message, dot...)
sign := mac.Sum(nil)
encodedSign := base64.RawURLEncoding.EncodeToString(sign)
return append(message, encodedSign...), nil
}
func ParseAndValidateCustom(token, key []byte, algo *Algorithm, claims interface{}, validator ValidatorFunction) error {
header := acquireHeader()
defer releaseHeader(header)
sign, message, err := ParseCustom(token, header, claims)
if err != nil {
return err
}
if header.Algorithm != algo.Name {
return ErrWrongAlgorithm
}
err = Verify(algo, message, sign, key)
if err != nil {
return err
}
if !validator(claims) {
return ErrExpiredToken
}
return nil
}
func ParseCustom(token []byte, header *Header, claims interface{}) ([]byte, []byte, error) {
splitted := bytes.Split(token, dot)
if len(splitted) != 3 {
return nil, nil, ErrMalformedToken
}
err := header.Decode(splitted[0])
if err != nil {
return nil, nil, ErrMalformedToken
}
err = decodeCustomClaims(splitted[1], claims)
if err != nil {
return nil, nil, ErrMalformedToken
}
dotted := append(splitted[0], dot...)
dotted = append(dotted, splitted[1]...)
return splitted[2], dotted, nil
}
func NewHS256Custom(key []byte, claims interface{}) ([]byte, error) {
return NewWithCustom(key, hs256Algo, claims)
}
func ParseHS256Custom(key, token []byte, claims interface{}, validator ValidatorFunction) error {
return ParseAndValidateCustom(token, key, hs256Algo, claims, validator)
}
func NewHS512Custom(key []byte, claims interface{}) ([]byte, error) {
return NewWithCustom(key, hs512Algo, claims)
}
func ParseHS512Custom(key, token []byte, claims interface{}, validator ValidatorFunction) error {
return ParseAndValidateCustom(token, key, hs512Algo, claims, validator)
}
func NewHS384Custom(key []byte, claims interface{}) ([]byte, error) {
return NewWithCustom(key, hs384Algo, claims)
}
func ParseHS384Custom(key, token []byte, claims interface{}, validator ValidatorFunction) error {
return ParseAndValidateCustom(token, key, hs384Algo, claims, validator)
}