/
token.go
115 lines (98 loc) · 2.28 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
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
package client
import (
"bytes"
"encoding/json"
"errors"
"net/http"
"time"
)
type tokenReq struct {
CorpID string `json:"app_id"`
CorpSecret string `json:"app_secret"`
}
// Token ...
type Token struct {
AppAccessToken string `json:"app_access_token,omitempty"`
TenantAccessToken string `json:"tenant_access_token,omitempty"`
ExpiresIn int64 `json:"expires,omitempty"` // seconds // 过期时间,单位为秒(两小时失效)
Error
}
// TokenHolder ...
type TokenHolder struct {
currToken *Token
uri string
method string
apiAuths string
corpID string
corpSecret string
expiresAt int64
}
var (
errEmptyAuths = errors.New("empty auth string or corpID and corpSecret")
)
func NewTokenHolder(uri string) *TokenHolder {
return &TokenHolder{
uri: uri,
method: "POST",
}
}
func (th *TokenHolder) SetAuth(auths string) {
th.apiAuths = auths
}
func (th *TokenHolder) SetCorp(id, secret string) {
th.corpID = id
th.corpSecret = secret
}
func (th *TokenHolder) Expired() bool {
return th.expiresAt < time.Now().Unix()
}
func (th *TokenHolder) Valid() bool {
if th.currToken == nil {
return false
}
return !th.Expired()
}
func (th *TokenHolder) GetAuthToken() (token string, err error) {
if !th.Valid() {
logger().Debugw("token is nil or expired, refreshing it")
th.currToken, err = th.requestToken()
if err != nil {
return "", err
}
logger().Infow("th got new OK", "token", th.currToken)
th.expiresAt = time.Now().Unix() + th.currToken.ExpiresIn
}
if th.currToken.TenantAccessToken != "" {
token = th.currToken.TenantAccessToken
} else {
token = th.currToken.AppAccessToken
}
return
}
func (th *TokenHolder) requestToken() (token *Token, err error) {
treq := &tokenReq{
CorpID: th.corpID,
CorpSecret: th.corpSecret,
}
logger().Debugw("request token", "corpID", th.corpID)
body, _ := json.Marshal(treq)
req, err := http.NewRequest("POST", th.uri, bytes.NewReader(body))
if err != nil {
return nil, err
}
hc := &http.Client{Transport: tr}
var resp []byte
resp, err = doRequest(hc, req)
if err != nil {
logger().Infow("th request fail", "err", err)
return
}
obj := &Token{}
err = parseResult(resp, obj)
if err != nil {
logger().Infow("parseResult fail", "err", err)
return
}
token = obj
return
}