- refactor refresh token.

This commit is contained in:
gazebo
2018-06-27 10:37:07 +08:00
parent e0ceb0ad0a
commit b0d9fad396
3 changed files with 99 additions and 31 deletions

View File

@@ -9,6 +9,7 @@ import (
"net/url" "net/url"
"sort" "sort"
"strings" "strings"
"sync"
"git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/platformapi"
@@ -17,9 +18,11 @@ import (
const ( const (
sandboxURL = "https://open-api-sandbox.shop.ele.me/api/v1" 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" snadboxTokenURL = "https://open-api-sandbox.shop.ele.me/token"
prodURL = "https://open-api.shop.ele.me/api/v1" 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" prodTokenURL = "https://open-api.shop.ele.me/token"
signKey = "signature" signKey = "signature"
@@ -45,6 +48,7 @@ type API struct {
url *url.URL url *url.URL
client *http.Client client *http.Client
config *platformapi.APIConfig config *platformapi.APIConfig
locker sync.RWMutex
} }
type payload struct { type payload struct {
@@ -79,6 +83,24 @@ func New(token, appKey, secret string, isProd bool, config ...*platformapi.APICo
return api 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 { func (a *API) signParamsMap(mapData map[string]interface{}, prefix string) string {
keyValues := make([]string, 0) keyValues := make([]string, 0)
for k, v := range mapData { 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 { func (a *API) signParams(action string, pl *payload) string {
mapData := utils.MergeMaps(pl.Metas, pl.Params) 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) { 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{ pl := &payload{
Token: a.token, Token: a.GetToken(),
Nop: "1.0.0", Nop: "1.0.0",
Metas: metas, Metas: metas,
Params: params, Params: params,
@@ -174,33 +196,59 @@ func (a *API) getTokenURL() string {
return snadboxTokenURL return snadboxTokenURL
} }
func (a *API) RefreshToken() (retVal *TokenInfo, err error) { 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) params2 := make(url.Values)
params2["grant_type"] = []string{"client_credentials"} for k, v := range params {
params2["scope"] = []string{"all"} params2[k] = []string{fmt.Sprint(v)}
// baseapi.SugarLogger.Debug(params2.Encode()) }
request, _ := http.NewRequest("POST", a.getTokenURL(), strings.NewReader(params2.Encode())) request, _ = http.NewRequest("POST", baseURL, strings.NewReader(params2.Encode()))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(a.appKey+":"+a.secret))) 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) { err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
jsonResult1, err := utils.HTTPResponse2Json(response) jsonResult1, err := utils.HTTPResponse2Json(response)
if err != nil { if err != nil {
return platformapi.ErrLevelGeneralFail, err return platformapi.ErrLevelGeneralFail, err
} }
retVal = &TokenInfo{} retVal = jsonResult1
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.ErrLevelSuccess, nil
}
return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong
}) })
return retVal, err 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
}

View File

@@ -63,8 +63,8 @@ func TestCallbackSign(t *testing.T) {
} }
} }
func TestRefreshToken(t *testing.T) { func TestRefreshTokenIndividual(t *testing.T) {
result, err := elmapi.RefreshToken() result, err := elmapi.RefreshTokenIndividual()
if err != nil { if err != nil {
t.Fatal(err.Error()) t.Fatal(err.Error())
} }

View File

@@ -3,6 +3,7 @@ package weixinapi
import ( import (
"net/http" "net/http"
"net/url" "net/url"
"sync"
"git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/platformapi"
@@ -34,6 +35,7 @@ type API struct {
secret string secret string
client *http.Client client *http.Client
config *platformapi.APIConfig config *platformapi.APIConfig
locker sync.RWMutex
} }
func New(appID, secret string, config ...*platformapi.APIConfig) *API { 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) { func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal interface{}, err error) {
if params == nil { if params == nil {
panic("params is 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["appid"] = a.appID
params2["secret"] = a.secret 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()) // baseapi.SugarLogger.Debug(url.String())
request := &http.Request{ request := &http.Request{
Method: "GET", Method: "GET",
URL: url, URL: fullURL,
} }
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) { err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
jsonResult1, err := utils.HTTPResponse2Json(response) jsonResult1, err := utils.HTTPResponse2Json(response)
@@ -108,6 +128,6 @@ func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) {
tokenInfo = result.(*TokenInfo) tokenInfo = result.(*TokenInfo)
// update my token too. // update my token too.
a.token = tokenInfo.AccessToken a.SetToken(tokenInfo.AccessToken)
return tokenInfo, nil return tokenInfo, nil
} }