- elm and weixin token refresh.

This commit is contained in:
gazebo
2018-06-26 15:26:39 +08:00
parent 910c9e02d1
commit ee4e88594d
8 changed files with 241 additions and 30 deletions

View File

@@ -13,8 +13,8 @@ import (
)
const (
sandboxURL = "http://newopen.qa.imdada.cn/"
prodURL = "http://newopen.imdada.cn/"
sandboxURL = "http://newopen.qa.imdada.cn"
prodURL = "http://newopen.imdada.cn"
signKey = "signature"
)
@@ -109,7 +109,7 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R
}
params2[signKey] = a.signParams(params2)
params2Bytes := utils.MustMarshal(params2)
request, _ := http.NewRequest("POST", a.url+action, bytes.NewReader(params2Bytes))
request, _ := http.NewRequest("POST", a.url+"/"+action, bytes.NewReader(params2Bytes))
request.Header.Set("Content-Type", "application/json")
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {

View File

@@ -2,6 +2,7 @@ package elmapi
import (
"crypto/md5"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
@@ -15,9 +16,13 @@ import (
)
const (
sandboxURL = "https://open-api-sandbox.shop.ele.me/api/v1/"
prodURL = "https://open-api.shop.ele.me/api/v1/"
signKey = "signature"
sandboxURL = "https://open-api-sandbox.shop.ele.me/api/v1"
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"
signKey = "signature"
)
type ResponseResult struct {
@@ -26,10 +31,17 @@ type ResponseResult struct {
Error map[string]interface{}
}
type TokenInfo struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
type API struct {
token string
appKey string
secret string
isProd bool
url *url.URL
client *http.Client
config *platformapi.APIConfig
@@ -54,14 +66,15 @@ func New(token, appKey, secret string, isProd bool, config ...*platformapi.APICo
token: token,
appKey: appKey,
secret: secret,
isProd: isProd,
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
if isProd {
api.url, _ = url.Parse(prodURL)
api.url, _ = url.Parse(prodURL + "/")
} else {
api.url, _ = url.Parse(sandboxURL)
api.url, _ = url.Parse(sandboxURL + "/")
}
return api
}
@@ -153,3 +166,41 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R
return retVal, err
}
func (a *API) getTokenURL() string {
if a.isProd {
return prodTokenURL
}
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)))
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
})
return retVal, err
}

View File

@@ -20,10 +20,10 @@ func init() {
baseapi.Init(sugarLogger)
// sandbox
// elmapi = New("b4f7e424475c3758c111dc60ceec3e2a", "RwT214gAsS", "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db", false)
elmapi = New("f22acad55e8b11ae146ad9295e20cf4e", "RwT214gAsS", "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db", false)
// prod
elmapi = New("bab2a27f99562f394b411dbb9a6214da", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true)
// elmapi = New("bab2a27f99562f394b411dbb9a6214da", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true)
}
func TestTest(t *testing.T) {
@@ -62,3 +62,11 @@ func TestCallbackSign(t *testing.T) {
t.Fatal(response, msg)
}
}
func TestRefreshToken(t *testing.T) {
result, err := elmapi.RefreshToken()
if err != nil {
t.Fatal(err.Error())
}
sugarLogger.Debug(result)
}

View File

@@ -40,7 +40,7 @@ const (
)
const (
prodURL = "https://openo2o.jd.com/djapi/%s"
prodURL = "https://openo2o.jd.com/djapi"
signKey = "sign"
AllPage = 0
DefaultPageSize = 50
@@ -107,23 +107,6 @@ func (a *API) signParams(jdParams map[string]interface{}) string {
return fmt.Sprintf("%X", md5.Sum([]byte(allStr)))
}
func generateURL(baseURL, apiStr string, params map[string]interface{}) string {
fullURL := ""
if params != nil {
for k, v := range params {
if fullURL == "" {
fullURL = "?"
} else {
fullURL += "&"
}
fullURL += k + "=" + url.QueryEscape(fmt.Sprint(v))
}
}
return fmt.Sprintf(baseURL, apiStr) + fullURL
}
func New(token, appKey, appSecret string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
@@ -159,7 +142,7 @@ func (a *API) AccessAPI(apiStr string, jdParams map[string]interface{}) (retVal
sign := a.signParams(params)
params[signKey] = sign
url, _ := url.Parse(generateURL(prodURL, apiStr, params))
url, _ := url.Parse(utils.GenerateGetURL(prodURL, apiStr, params))
request := &http.Request{
Method: "GET",
URL: url,

View File

@@ -84,7 +84,7 @@ func TestGenerateURL(t *testing.T) {
params["key"] = "v"
params["key2"] = "v2"
fullURL := generateURL(prodURL, "address/allcities", params)
fullURL := utils.GenerateGetURL(prodURL, "address/allcities", params)
response, err := http.Get(fullURL)
if err != nil {

View File

@@ -0,0 +1,113 @@
package weixinapi
import (
"net/http"
"net/url"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
const (
prodURL = "https://api.weixin.qq.com"
)
const (
ResponseCodeBusy = -1
ResponseCodeSuccess = 0
)
type TokenInfo struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
}
type ErrorInfo struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
}
type API struct {
token string
appID string
secret string
client *http.Client
config *platformapi.APIConfig
}
func New(appID, secret string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
curConfig = *config[0]
}
return &API{
appID: appID,
secret: secret,
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
}
func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal interface{}, err error) {
if params == nil {
panic("params is nil!")
}
params2 := make(map[string]interface{})
for k, v := range params {
params2[k] = v
}
params2["appid"] = a.appID
params2["secret"] = a.secret
url, _ := url.Parse(utils.GenerateGetURL(prodURL, action, params2))
// baseapi.SugarLogger.Debug(url.String())
request := &http.Request{
Method: "GET",
URL: url,
}
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, platformapi.ErrResponseDataFormatWrong
}
var errInfo *ErrorInfo
// 微信的返回值,在错误与正常情况下,结构是完全不一样的
if errCode, ok := jsonResult1["errcode"]; ok {
errInfo = &ErrorInfo{
ErrCode: int(utils.MustInterface2Int64(errCode)),
ErrMsg: jsonResult1["errmsg"].(string),
}
} else {
retVal = &TokenInfo{
AccessToken: jsonResult1["access_token"].(string),
ExpiresIn: int(utils.MustInterface2Int64(jsonResult1["expires_in"])),
}
}
if retVal != nil {
return platformapi.ErrLevelSuccess, nil
}
baseapi.SugarLogger.Warnf("response business code is not ok, data:%v, code:%v", jsonResult1, errInfo.ErrCode)
newErr := utils.NewErrorIntCode(errInfo.ErrMsg, errInfo.ErrCode)
if errInfo.ErrCode == ResponseCodeBusy {
return platformapi.ErrLevelRecoverableErr, newErr
}
return platformapi.ErrLevelCodeIsNotOK, newErr
})
return retVal, err
}
func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) {
result, err := a.AccessAPI("cgi-bin/token", utils.Params2Map("grant_type", "client_credential"))
if err != nil {
return nil, err
}
tokenInfo = result.(*TokenInfo)
// update my token too.
a.token = tokenInfo.AccessToken
return tokenInfo, nil
}

View File

@@ -0,0 +1,40 @@
package weixinapi
import (
"testing"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"go.uber.org/zap"
)
var (
weixinapi *API
sugarLogger *zap.SugaredLogger
)
func init() {
logger, _ := zap.NewDevelopment()
sugarLogger = logger.Sugar()
baseapi.Init(sugarLogger)
weixinapi = New("wxbf235770edaabc5c", "ba32b269a068a5b72486a0beafd171e8")
}
func handleError(t *testing.T, err error) {
if err != nil {
sugarLogger.Debug(err)
t.Fatal(err.Error())
}
}
func TestTest(t *testing.T) {
sugarLogger.Debug(utils.GetCurTimeStr())
}
func TestRefreshToken(t *testing.T) {
result, err := weixinapi.RefreshToken()
if err != nil {
t.Fatal(err.Error())
}
sugarLogger.Debug(result)
}

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strconv"
"strings"
@@ -232,3 +233,18 @@ func Params2Map(key1, value1 interface{}, kv ...interface{}) (retVal map[string]
return retVal
}
func GenerateGetURL(baseURL, apiStr string, params map[string]interface{}) string {
queryString := ""
if params != nil {
for k, v := range params {
if queryString == "" {
queryString = "?"
} else {
queryString += "&"
}
queryString += k + "=" + url.QueryEscape(fmt.Sprint(v))
}
}
return baseURL + "/" + apiStr + queryString
}