-
Notifications
You must be signed in to change notification settings - Fork 1
/
token.go
101 lines (81 loc) · 1.96 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
package nuonuo
import (
"context"
"fmt"
"sync"
"time"
"github.com/go-resty/resty/v2"
)
type TokenController interface {
GetToken(ctx context.Context) (string, error)
}
type permanentToken struct {
token string
}
func NewPermanentToken(token string) TokenController {
return &permanentToken{
token: token,
}
}
func (pt *permanentToken) GetToken(ctx context.Context) (string, error) {
return pt.token, nil
}
type oauthToken struct {
appKey string
appSecret string
restyClient *resty.Client
token string
isPermanent bool
expiresTime time.Time
mu sync.Mutex
}
func NewOAuthToken(appKey, appSecret string) TokenController {
return &oauthToken{
appKey: appKey,
appSecret: appSecret,
restyClient: resty.New(),
}
}
func (ot *oauthToken) GetToken(ctx context.Context) (string, error) {
ot.mu.Lock()
defer ot.mu.Unlock()
if !ot.isValid() {
if err := ot.refreshToken(ctx); err != nil {
return "", err
}
}
return ot.token, nil
}
func (ot *oauthToken) isValid() bool {
return ot.token != "" && (ot.isPermanent || time.Now().Before(ot.expiresTime))
}
func (ot *oauthToken) refreshToken(ctx context.Context) error {
var result struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
}
resp, err := ot.restyClient.R().
SetContext(ctx).
SetHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8").
SetFormData(map[string]string{
"client_id": ot.appKey,
"client_secret": ot.appSecret,
"grant_type": "client_credentials",
}).
ForceContentType("application/json").
SetResult(&result).
Post("https://open.nuonuo.com/accessToken")
if err != nil {
return err
}
if resp.IsError() {
return fmt.Errorf("http status: %s, body: %s", resp.Status(), resp.Body())
}
ot.token = result.AccessToken
if result.ExpiresIn < 0 {
ot.isPermanent = true
} else {
ot.expiresTime = time.Now().Add(time.Second * time.Duration(result.ExpiresIn-5))
}
return nil
}