From b0d9fad3966adc30781420eeacbf9217ad036ddc Mon Sep 17 00:00:00 2001 From: gazebo Date: Wed, 27 Jun 2018 10:37:07 +0800 Subject: [PATCH] - refactor refresh token. --- platformapi/elmapi/elmapi.go | 100 +++++++++++++++++++++-------- platformapi/elmapi/elmapi_test.go | 4 +- platformapi/weixinapi/weixinapi.go | 26 +++++++- 3 files changed, 99 insertions(+), 31 deletions(-) diff --git a/platformapi/elmapi/elmapi.go b/platformapi/elmapi/elmapi.go index 77a5aafb..a7c0d439 100644 --- a/platformapi/elmapi/elmapi.go +++ b/platformapi/elmapi/elmapi.go @@ -9,6 +9,7 @@ import ( "net/url" "sort" "strings" + "sync" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi" @@ -16,11 +17,13 @@ import ( ) const ( - sandboxURL = "https://open-api-sandbox.shop.ele.me/api/v1" - snadboxTokenURL = "https://open-api-sandbox.shop.ele.me/token" + sandboxURL = "https://open-api-sandbox.shop.ele.me/api/v1" + sandboxAuthorizeURL = "https://open-api-sandbox.shop.ele.me/authorize" + snadboxTokenURL = "https://open-api-sandbox.shop.ele.me/token" - prodURL = "https://open-api.shop.ele.me/api/v1" - prodTokenURL = "https://open-api.shop.ele.me/token" + prodURL = "https://open-api.shop.ele.me/api/v1" + prodAuthorizeURL = "https://open-api.shop.ele.me/authorize" + prodTokenURL = "https://open-api.shop.ele.me/token" signKey = "signature" ) @@ -45,6 +48,7 @@ type API struct { url *url.URL client *http.Client config *platformapi.APIConfig + locker sync.RWMutex } type payload struct { @@ -79,6 +83,24 @@ func New(token, appKey, secret string, isProd bool, config ...*platformapi.APICo return api } +func (a *API) SetToken(newToken string) bool { + curToken := a.GetToken() + if curToken != newToken { + a.locker.Lock() + defer a.locker.Unlock() + a.token = newToken + return true + } + + return false +} + +func (a *API) GetToken() string { + a.locker.RLock() + defer a.locker.RUnlock() + return a.token +} + func (a *API) signParamsMap(mapData map[string]interface{}, prefix string) string { keyValues := make([]string, 0) for k, v := range mapData { @@ -102,7 +124,7 @@ func (a *API) signParamsMap(mapData map[string]interface{}, prefix string) strin func (a *API) signParams(action string, pl *payload) string { mapData := utils.MergeMaps(pl.Metas, pl.Params) - return a.signParamsMap(mapData, action+a.token) + return a.signParamsMap(mapData, action+a.GetToken()) } func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *ResponseResult, err error) { @@ -115,7 +137,7 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R } pl := &payload{ - Token: a.token, + Token: a.GetToken(), Nop: "1.0.0", Metas: metas, Params: params, @@ -174,33 +196,59 @@ func (a *API) getTokenURL() string { return snadboxTokenURL } -func (a *API) RefreshToken() (retVal *TokenInfo, err error) { - params2 := make(url.Values) - params2["grant_type"] = []string{"client_credentials"} - params2["scope"] = []string{"all"} - // baseapi.SugarLogger.Debug(params2.Encode()) - request, _ := http.NewRequest("POST", a.getTokenURL(), strings.NewReader(params2.Encode())) - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") - request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(a.appKey+":"+a.secret))) +func (a *API) getAuthorizeURL() string { + if a.isProd { + return prodAuthorizeURL + } + return sandboxAuthorizeURL +} +func (a *API) AcccessAPI2(baseURL string, params map[string]interface{}, method string) (retVal map[string]interface{}, err error) { + var request *http.Request + if method == "POST" { + params2 := make(url.Values) + for k, v := range params { + params2[k] = []string{fmt.Sprint(v)} + } + request, _ = http.NewRequest("POST", baseURL, strings.NewReader(params2.Encode())) + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(a.appKey+":"+a.secret))) + } else { + fullURL, _ := url.Parse(utils.GenerateGetURL(baseURL, "", params)) + // baseapi.SugarLogger.Debug(url.String()) + request = &http.Request{ + Method: "GET", + URL: fullURL, + } + } err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) { jsonResult1, err := utils.HTTPResponse2Json(response) if err != nil { return platformapi.ErrLevelGeneralFail, err } - retVal = &TokenInfo{} - - if accessToken, ok := jsonResult1["access_token"]; ok { - retVal.AccessToken = accessToken.(string) - retVal.TokenType = jsonResult1["token_type"].(string) - retVal.ExpiresIn = int(utils.MustInterface2Int64(jsonResult1["expires_in"])) - - // update my token too. - a.token = retVal.AccessToken - return platformapi.ErrLevelSuccess, nil - } - return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong + retVal = jsonResult1 + return platformapi.ErrLevelSuccess, nil }) return retVal, err } + +func (a *API) RefreshTokenIndividual() (retVal *TokenInfo, err error) { + result, err := a.AcccessAPI2(a.getTokenURL(), utils.Params2Map("grant_type", "client_credentials", "scope", "all"), "POST") + if err != nil { + return nil, err + } + retVal = &TokenInfo{} + + if accessToken, ok := result["access_token"]; ok { + retVal.AccessToken = accessToken.(string) + retVal.TokenType = result["token_type"].(string) + retVal.ExpiresIn = int(utils.MustInterface2Int64(result["expires_in"])) + + // update my token too. + a.SetToken(retVal.AccessToken) + return retVal, nil + } + + return nil, platformapi.ErrResponseDataFormatWrong +} diff --git a/platformapi/elmapi/elmapi_test.go b/platformapi/elmapi/elmapi_test.go index 90cc6117..549e978e 100644 --- a/platformapi/elmapi/elmapi_test.go +++ b/platformapi/elmapi/elmapi_test.go @@ -63,8 +63,8 @@ func TestCallbackSign(t *testing.T) { } } -func TestRefreshToken(t *testing.T) { - result, err := elmapi.RefreshToken() +func TestRefreshTokenIndividual(t *testing.T) { + result, err := elmapi.RefreshTokenIndividual() if err != nil { t.Fatal(err.Error()) } diff --git a/platformapi/weixinapi/weixinapi.go b/platformapi/weixinapi/weixinapi.go index ecb74a48..66e78477 100644 --- a/platformapi/weixinapi/weixinapi.go +++ b/platformapi/weixinapi/weixinapi.go @@ -3,6 +3,7 @@ package weixinapi import ( "net/http" "net/url" + "sync" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi" @@ -34,6 +35,7 @@ type API struct { secret string client *http.Client config *platformapi.APIConfig + locker sync.RWMutex } func New(appID, secret string, config ...*platformapi.APIConfig) *API { @@ -49,6 +51,24 @@ func New(appID, secret string, config ...*platformapi.APIConfig) *API { } } +func (a *API) SetToken(newToken string) bool { + curToken := a.GetToken() + if curToken != newToken { + a.locker.Lock() + defer a.locker.Unlock() + a.token = newToken + return true + } + + return false +} + +func (a *API) GetToken() string { + a.locker.RLock() + defer a.locker.RUnlock() + return a.token +} + func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal interface{}, err error) { if params == nil { panic("params is nil!") @@ -60,11 +80,11 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal in } params2["appid"] = a.appID params2["secret"] = a.secret - url, _ := url.Parse(utils.GenerateGetURL(prodURL, action, params2)) + fullURL, _ := url.Parse(utils.GenerateGetURL(prodURL, action, params2)) // baseapi.SugarLogger.Debug(url.String()) request := &http.Request{ Method: "GET", - URL: url, + URL: fullURL, } err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) { jsonResult1, err := utils.HTTPResponse2Json(response) @@ -108,6 +128,6 @@ func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) { tokenInfo = result.(*TokenInfo) // update my token too. - a.token = tokenInfo.AccessToken + a.SetToken(tokenInfo.AccessToken) return tokenInfo, nil }