-
Notifications
You must be signed in to change notification settings - Fork 0
/
jwt.go
132 lines (115 loc) · 2.94 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
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package jwt
import (
"errors"
"github.com/dgrijalva/jwt-go"
"sync"
"sync/atomic"
"time"
)
const claimHistoryResetDuration = time.Hour * 24
type (
//ParseOption ParseOption
ParseOption func(parser *TokenParser)
//TokenParser TokenParser
TokenParser struct {
resetTime time.Duration
resetDuration time.Duration
history sync.Map
}
)
// NewTokenParser 新的TokenParser
func NewTokenParser(opts ...ParseOption) *TokenParser {
parser := &TokenParser{
resetTime: time.Since(time.Now()),
resetDuration: claimHistoryResetDuration,
}
for _, opt := range opts {
opt(parser)
}
return parser
}
//ParseToken 格式化Token
func (tp *TokenParser) ParseToken(secret, prevSecret string) ( token *jwt.Token, err error) {
if len(prevSecret) > 0 {
}
return
}
//CreateToken 生成Token
func (tp *TokenParser) CreateToken(secret, prevSecret string) ( token *jwt.Token, err error) {
if len(prevSecret) > 0 {
}
return
}
// loadCount 个数
func (tp *TokenParser) loadCount(secret string) uint64 {
value, ok := tp.history.Load(secret)
if ok {
return *value.(*uint64)
}
return 0
}
// incrementCount 计数
func (tp *TokenParser) incrementCount(secret string) {
now := time.Since(time.Now())
if tp.resetTime+tp.resetDuration < now {
tp.history.Range(func(key, value interface{}) bool {
tp.history.Delete(key)
return true
})
}
value, ok := tp.history.Load(secret)
if ok {
atomic.AddUint64(value.(*uint64), 1)
} else {
var count uint64 = 1
tp.history.Store(secret, &count)
}
}
var ks []byte
//InitJwt InitJwt
func InitJwt(key string) {
ks = []byte(key)
}
//CustomClaims CustomClaims
type CustomClaims struct {
ID uint32 `json:"id"`
IP string `json:"ip"`
EX string `json:"ex"`
}
//CreateToken CreateToken
func CreateToken(id CustomClaims, key ...interface{}) (token string, err error) {
claim := jwt.MapClaims{
"id": id.ID,
"ip": id.IP,
"ex": time.Now().String(),
}
tokens := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
token, err = tokens.SignedString(ks)
return token, err
}
//ParseToken ParseToken
func ParseToken(tokens string) (id CustomClaims, err error) {
token, err := jwt.Parse(tokens, secret())
if err != nil {
return
}
claim, ok := token.Claims.(jwt.MapClaims)
if !ok {
err = errors.New("cannot convert claim to mapclaim")
return id, err
}
//验证token,如果token被修改过则为false
if !token.Valid {
err = errors.New("token is invalid")
return id, err
}
id.ID = uint32(claim["id"].(float64))
id.IP = claim["ip"].(string)
id.EX = claim["ex"].(string)
return id, err
}
func secret() jwt.Keyfunc {
return func(token *jwt.Token) (interface{}, error) {
return ks, nil
}
}