-
Notifications
You must be signed in to change notification settings - Fork 0
/
component_access_token.go
221 lines (189 loc) · 6.18 KB
/
component_access_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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package context
import (
"encoding/json"
"fmt"
"time"
"github.com/sqeven/wechat/util"
)
const (
componentAccessTokenURL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"
getPreCodeURL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=%s"
queryAuthURL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=%s"
refreshTokenURL = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=%s"
getComponentInfoURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%s"
getComponentConfigURL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token=%s"
)
// ComponentAccessToken 第三方平台
type ComponentAccessToken struct {
AccessToken string `json:"component_access_token"`
ExpiresIn int64 `json:"expires_in"`
}
// GetComponentAccessToken 获取 ComponentAccessToken
func (ctx *Context) GetComponentAccessToken() (string, error) {
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
val := ctx.Cache.Get(accessTokenCacheKey)
if val == nil {
return "", fmt.Errorf("cann't get component access token")
}
return val.(string), nil
}
// SetComponentAccessToken 通过component_verify_ticket 获取 ComponentAccessToken
func (ctx *Context) SetComponentAccessToken(verifyTicket string) (*ComponentAccessToken, error) {
body := map[string]string{
"component_appid": ctx.AppID,
"component_appsecret": ctx.AppSecret,
"component_verify_ticket": verifyTicket,
}
respBody, err := util.PostJSON(componentAccessTokenURL, body)
if err != nil {
return nil, err
}
at := &ComponentAccessToken{}
if err := json.Unmarshal(respBody, at); err != nil {
return nil, err
}
accessTokenCacheKey := fmt.Sprintf("component_access_token_%s", ctx.AppID)
expires := at.ExpiresIn - 1500
ctx.Cache.Set(accessTokenCacheKey, at.AccessToken, time.Duration(expires)*time.Second)
return at, nil
}
// GetPreCode 获取预授权码
func (ctx *Context) GetPreCode() (string, error) {
cat, err := ctx.GetComponentAccessToken()
if err != nil {
return "", err
}
req := map[string]string{
"component_appid": ctx.AppID,
}
uri := fmt.Sprintf(getPreCodeURL, cat)
body, err := util.PostJSON(uri, req)
if err != nil {
return "", err
}
var ret struct {
PreCode string `json:"pre_auth_code"`
}
if err := json.Unmarshal(body, &ret); err != nil {
return "", err
}
return ret.PreCode, nil
}
// ID 微信返回接口中各种类型字段
type ID struct {
ID int `json:"id"`
}
// AuthBaseInfo 授权的基本信息
type AuthBaseInfo struct {
AuthrAccessToken
FuncInfo []AuthFuncInfo `json:"func_info"`
}
// AuthFuncInfo 授权的接口内容
type AuthFuncInfo struct {
FuncscopeCategory ID `json:"funcscope_category"`
}
// AuthrAccessToken 授权方AccessToken
type AuthrAccessToken struct {
Appid string `json:"authorizer_appid"`
AccessToken string `json:"authorizer_access_token"`
ExpiresIn int64 `json:"expires_in"`
RefreshToken string `json:"authorizer_refresh_token"`
}
// QueryAuthCode 使用授权码换取公众号或小程序的接口调用凭据和授权信息
func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
cat, err := ctx.GetComponentAccessToken()
if err != nil {
return nil, err
}
req := map[string]string{
"component_appid": ctx.AppID,
"authorization_code": authCode,
}
uri := fmt.Sprintf(queryAuthURL, cat)
body, err := util.PostJSON(uri, req)
if err != nil {
return nil, err
}
var ret struct {
Info *AuthBaseInfo `json:"authorization_info"`
}
if err := json.Unmarshal(body, &ret); err != nil {
return nil, err
}
return ret.Info, nil
}
// RefreshAuthrToken 获取(刷新)授权公众号或小程序的接口调用凭据(令牌)
func (ctx *Context) RefreshAuthrToken(appid, refreshToken string) (*AuthrAccessToken, error) {
cat, err := ctx.GetComponentAccessToken()
if err != nil {
return nil, err
}
req := map[string]string{
"component_appid": ctx.AppID,
"authorizer_appid": appid,
"authorizer_refresh_token": refreshToken,
}
uri := fmt.Sprintf(refreshTokenURL, cat)
body, err := util.PostJSON(uri, req)
if err != nil {
return nil, err
}
ret := &AuthrAccessToken{}
if err := json.Unmarshal(body, ret); err != nil {
return nil, err
}
authrTokenKey := "authorizer_access_token_" + appid
ctx.Cache.Set(authrTokenKey, ret.AccessToken, time.Minute*80)
return ret, nil
}
// GetAuthrAccessToken 获取授权方AccessToken
func (ctx *Context) GetAuthrAccessToken(appid string) (string, error) {
authrTokenKey := "authorizer_access_token_" + appid
val := ctx.Cache.Get(authrTokenKey)
if val == nil {
return "", fmt.Errorf("cannot get authorizer %s access token", appid)
}
return val.(string), nil
}
// AuthorizerInfo 授权方详细信息
type AuthorizerInfo struct {
NickName string `json:"nick_name"`
HeadImg string `json:"head_img"`
ServiceTypeInfo ID `json:"service_type_info"`
VerifyTypeInfo ID `json:"verify_type_info"`
UserName string `json:"user_name"`
PrincipalName string `json:"principal_name"`
BusinessInfo struct {
OpenStore string `json:"open_store"`
OpenScan string `json:"open_scan"`
OpenPay string `json:"open_pay"`
OpenCard string `json:"open_card"`
OpenShake string `json:"open_shake"`
}
Alias string `json:"alias"`
QrcodeURL string `json:"qrcode_url"`
}
// GetAuthrInfo 获取授权方的帐号基本信息
func (ctx *Context) GetAuthrInfo(appid string) (*AuthorizerInfo, *AuthBaseInfo, error) {
cat, err := ctx.GetComponentAccessToken()
if err != nil {
return nil, nil, err
}
req := map[string]string{
"component_appid": ctx.AppID,
"authorizer_appid": appid,
}
uri := fmt.Sprintf(getComponentInfoURL, cat)
body, err := util.PostJSON(uri, req)
if err != nil {
return nil, nil, err
}
var ret struct {
AuthorizerInfo *AuthorizerInfo `json:"authorizer_info"`
AuthorizationInfo *AuthBaseInfo `json:"authorization_info"`
}
if err := json.Unmarshal(body, &ret); err != nil {
return nil, nil, err
}
return ret.AuthorizerInfo, ret.AuthorizationInfo, nil
}