- 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"
"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
}

View File

@@ -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())
}

View File

@@ -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
}