-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtoken.go
89 lines (85 loc) · 2.3 KB
/
token.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
package kuu
import (
"errors"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin/binding"
uuid "github.com/satori/go.uuid"
"gopkg.in/guregu/null.v3"
"strings"
"time"
)
type GenTokenDesc struct {
UID uint
Username string
Exp int64 `binding:"required"`
Type string
Desc string
Payload jwt.MapClaims
IsAPIKey bool
ForcePayload bool // 是否强制使用Payload参数值作为jwt的payload
}
// GenToken
func GenToken(desc GenTokenDesc) (secretData *SignSecret, err error) {
if err := binding.Validator.ValidateStruct(&desc); err != nil {
return nil, err
}
if desc.IsAPIKey && desc.Desc == "" {
return nil, errors.New("API Keys needs a description")
}
// 设置JWT令牌信息
iat := time.Now().Unix()
desc.Payload["iat"] = iat // 签发时间:必须用全小写iat
desc.Payload["exp"] = desc.Exp // 过期时间:必须用全小写exp
desc.Payload["_k"] = strings.ReplaceAll(uuid.NewV4().String(), "-", "")
// 兼容未传递SubDocID时自动查询
var (
subDocID uint
user = GetUserFromCache(desc.UID)
)
if v, err := user.GetSubDocID(desc.Type); err != nil {
return nil, err
} else {
subDocID = v
}
// 生成新密钥
secretData = &SignSecret{
UID: desc.UID,
Username: desc.Username,
Secret: strings.ReplaceAll(uuid.NewV4().String(), "-", ""),
Iat: iat,
Exp: desc.Exp,
Method: SignMethodLogin,
SubDocID: subDocID,
Payload: JSONStringify(desc.Payload),
Desc: desc.Desc,
Type: desc.Type,
IsAPIKey: null.NewBool(desc.IsAPIKey, true),
}
// 签发令牌
var tokenPayload jwt.MapClaims
if desc.ForcePayload {
tokenPayload = desc.Payload
} else {
tokenPayload = jwt.MapClaims{
"_k": desc.Payload["_k"],
"UID": desc.Payload["UID"],
"iat": desc.Payload["iat"],
"exp": desc.Payload["exp"],
}
}
if signed, err := EncodedToken(tokenPayload, secretData.Secret); err != nil {
return secretData, err
} else {
secretData.Token = signed
}
desc.Payload[TokenKey] = secretData.Token
if err = DB().Create(secretData).Error; err != nil {
return
}
// 将secret存入缓存
expDur := time.Unix(secretData.Exp, 0).Sub(time.Unix(secretData.Iat, 0))
SetCacheString(secretData.Token, JSONStringify(secretData, false), expDur)
// 保存登入历史
saveHistory(secretData)
return
}