Skip to content

Commit 91db439

Browse files
authored
Merge pull request #1 from ArtisanCloud/feature/auth
Feature/auth
2 parents 010a86d + 7c519f8 commit 91db439

24 files changed

+855
-22
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
.DS_Store
33

44
environment.yml
5-
environment.yaml
5+
environment.yaml
6+
7+
temp.go

go.mod

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@ module github.com/ArtisanCloud/go-wechat
22

33
go 1.16
44

5+
//replace github.com/ArtisanCloud/go-libs => ../go-libs
6+
//
7+
//replace github.com/ArtisanCloud/go-socialite => ../go-socialite
8+
59
require (
6-
github.com/ArtisanCloud/go-libs v1.0.9 // indirect
7-
github.com/ArtisanCloud/ubt-go v1.0.4 // indirect
10+
github.com/ArtisanCloud/go-libs v1.0.11
11+
github.com/ArtisanCloud/go-socialite v1.0.0
12+
github.com/gin-gonic/gin v1.7.1 // indirect
13+
github.com/go-redis/redis/v8 v8.10.0 // indirect
14+
github.com/mattn/go-isatty v0.0.13 // indirect
15+
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
16+
golang.org/x/sys v0.0.0-20210608053332-aa57babbf139 // indirect
17+
gopkg.in/yaml.v2 v2.4.0 // indirect
818
)

go.sum

Lines changed: 49 additions & 16 deletions
Large diffs are not rendered by default.

main.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
package main
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
fmt2 "github.com/ArtisanCloud/go-libs/fmt"
6+
"github.com/ArtisanCloud/go-wechat/src/work"
7+
)
48

59
func main() {
610

7-
fmt.Printf("hello Wechat!")
11+
fmt.Printf("hello Wechat! \n")
812

9-
}
13+
config := GetConfig()
14+
15+
app := work.NewWork(config)
16+
//fmt2.Dump(app)
17+
fmt2.Dump(app.GetConfig())
18+
19+
//token := app.AccessToken.GetToken()
20+
//fmt2.Dump(token)
21+
22+
//cType := reflect.TypeOf((*app.Components)["base"].(*base.Client))
23+
//fmt.Printf("kind %s \n", cType.Kind())
24+
//fmt.Printf("type %v \n", cType)
25+
26+
//ips := app.Base.GetCallbackIp()
27+
//fmt2.Dump(ips)
28+
//domainIps := app.Base.GetAPIDomainIP()
29+
//fmt2.Dump(domainIps)
30+
31+
32+
33+
}

src/kernel/accessToken.go

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package kernel
2+
3+
import (
4+
"crypto/md5"
5+
"encoding/json"
6+
"fmt"
7+
"github.com/ArtisanCloud/go-libs/exception"
8+
http2 "github.com/ArtisanCloud/go-libs/http"
9+
httpContract "github.com/ArtisanCloud/go-libs/http/contract"
10+
"github.com/ArtisanCloud/go-libs/object"
11+
"github.com/ArtisanCloud/go-wechat/src/kernel/contract"
12+
response2 "github.com/ArtisanCloud/go-wechat/src/kernel/response"
13+
"net/http"
14+
"time"
15+
)
16+
17+
type AccessToken struct {
18+
App *ApplicationInterface
19+
20+
*http2.HttpRequest
21+
*http2.HttpResponse
22+
23+
RequestMethod string
24+
EndpointToGetToken string
25+
QueryName string
26+
Token object.HashMap
27+
TokenKey string
28+
CachePrefix string
29+
30+
*CacheToken
31+
32+
GetCredentials func() *object.StringMap
33+
}
34+
35+
func NewAccessToken(app *ApplicationInterface) *AccessToken {
36+
config := (*app).GetContainer().GetConfig()
37+
38+
token := &AccessToken{
39+
App: app,
40+
HttpRequest: http2.NewHttpRequest(config),
41+
42+
RequestMethod: "GET",
43+
EndpointToGetToken: "",
44+
QueryName: "",
45+
Token: nil,
46+
TokenKey: "access_token",
47+
CachePrefix: "ac.go.wechat.kernel.access_token.",
48+
49+
CacheToken: &CacheToken{},
50+
}
51+
52+
return token
53+
}
54+
55+
func (accessToken *AccessToken) GetRefreshedToken() *response2.ResponseGetToken {
56+
return accessToken.GetToken(true)
57+
}
58+
59+
func (accessToken *AccessToken) GetToken(refresh bool) (resToken *response2.ResponseGetToken) {
60+
cacheKey := accessToken.getCacheKey()
61+
cache := accessToken.getCache()
62+
63+
// get token from cache
64+
if !refresh && cache.Has(cacheKey) {
65+
value, err := cache.Get(cacheKey, nil)
66+
if err == nil {
67+
token := value.(*object.HashMap)
68+
return &response2.ResponseGetToken{
69+
AccessToken: (*token)[accessToken.TokenKey].(string),
70+
ExpiresIn: (*token)["expires_in"].(int),
71+
}
72+
}
73+
}
74+
75+
// request token from wx
76+
response := accessToken.requestToken(accessToken.GetCredentials())
77+
78+
//// save token into cache
79+
resToken = response.(*response2.ResponseGetToken)
80+
var expireIn int = 7200
81+
if resToken.ExpiresIn > 0 {
82+
expireIn = resToken.ExpiresIn
83+
}
84+
accessToken.SetToken(resToken.AccessToken, expireIn)
85+
86+
// tbd dispatch a event for AccessTokenRefresh
87+
88+
return resToken
89+
}
90+
91+
func (accessToken *AccessToken) SetToken(token string, lifeTime int) (tokenInterface contract.AccessTokenInterface, err error) {
92+
if lifeTime <= 0 {
93+
lifeTime = 7200
94+
}
95+
96+
// set token into cache
97+
cache := accessToken.getCache()
98+
err = cache.Set(accessToken.getCacheKey(), &object.HashMap{
99+
accessToken.TokenKey: token,
100+
"expires_in": lifeTime,
101+
}, time.Duration(lifeTime)*time.Second)
102+
103+
defer (&exception.Exception{}).HandleException(nil, "accessToken.set.token", nil)
104+
if !cache.Has(accessToken.getCacheKey()) {
105+
panic("Failed to cache access token.")
106+
return nil, err
107+
}
108+
return accessToken, err
109+
110+
}
111+
112+
func (accessToken *AccessToken) Refresh() contract.AccessTokenInterface {
113+
114+
return nil
115+
}
116+
117+
func (accessToken *AccessToken) requestToken(credentials *object.StringMap) httpContract.ResponseContract {
118+
119+
// tbf
120+
return &response2.ResponseGetToken{
121+
AccessToken: "FwhFYGuWs47wxxUQHf5gbOIwMBe8ohu3EUnhF-x6uw4VX55-m46bnQUHLJ1nM5R0WAVfrLHvdn6XJtkMkzRkN_E75edrNzWK6IZxx3RwUJNowZEg3dcU3NEygFGfzUEGLS5fiB4GtNPOi-HKUhQumAMcP0lncEij2Hjg95FTqS4YBRNVG4OL92h8RAiP-yllfDvt2URk6tntGe4HaxAGdA",
122+
ExpiresIn: 7200,
123+
ResponseWX: &response2.ResponseWX{
124+
ErrCode: 0,
125+
ErrMSG: "ok",
126+
},
127+
}
128+
129+
res := accessToken.sendRequest(credentials)
130+
token := res.(*response2.ResponseGetToken)
131+
defer (&exception.Exception{}).HandleException(nil, "accessToken.request.token", nil)
132+
if token == nil || token.AccessToken == "" {
133+
panic(fmt.Sprintf("Request access_token fail: %v", res))
134+
return nil
135+
}
136+
137+
return token
138+
}
139+
140+
func (accessToken *AccessToken) ApplyToRequest(request *http.Request, requestOptions *object.HashMap) *http.Request {
141+
142+
// query Access Token map
143+
mapToken := accessToken.getQuery()
144+
q := request.URL.Query()
145+
for key, value := range *mapToken {
146+
q.Set(key, value)
147+
}
148+
request.URL.RawQuery = q.Encode()
149+
150+
return request
151+
}
152+
153+
func (accessToken *AccessToken) sendRequest(credential *object.StringMap) httpContract.ResponseContract {
154+
155+
key := "json"
156+
if accessToken.RequestMethod == "GET" {
157+
key = "query"
158+
}
159+
options := &object.HashMap{
160+
key: credential,
161+
}
162+
163+
res := &response2.ResponseGetToken{}
164+
165+
accessToken.SetHttpClient(accessToken.GetHttpClient()).PerformRequest(
166+
accessToken.getEndpoint(),
167+
accessToken.RequestMethod,
168+
options,
169+
res,
170+
)
171+
return res
172+
}
173+
174+
func (accessToken *AccessToken) getCacheKey() string {
175+
data, _ := json.Marshal(accessToken.GetCredentials())
176+
buffer := md5.Sum(data)
177+
178+
return accessToken.CachePrefix + string(buffer[:])
179+
}
180+
181+
func (accessToken *AccessToken) getQuery() *object.StringMap {
182+
// set the current token key
183+
var key string
184+
if accessToken.QueryName != "" {
185+
key = accessToken.QueryName
186+
} else {
187+
key = accessToken.TokenKey
188+
}
189+
190+
// get token string map
191+
resToken := accessToken.GetToken(false)
192+
arrayReturn := &object.StringMap{
193+
key: resToken.AccessToken,
194+
}
195+
196+
return arrayReturn
197+
198+
}
199+
200+
func (accessToken *AccessToken) getEndpoint() string {
201+
defer (&exception.Exception{}).HandleException(nil, "accessToken.get.endpoint", accessToken)
202+
if accessToken.EndpointToGetToken == "" {
203+
panic("No endpoint for access token request.")
204+
return ""
205+
}
206+
207+
return accessToken.EndpointToGetToken
208+
}
209+
210+
func (accessToken *AccessToken) getTokenKey() string {
211+
return accessToken.TokenKey
212+
}

0 commit comments

Comments
 (0)