Files
baseapi/platformapi/uinapp/uinapp_token.go
邹宗楠 edd680602b 1
2023-03-20 17:27:47 +08:00

133 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package uinapp
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
"net/http"
"strings"
"sync"
"time"
)
type API struct {
appId string `json:"app_id"`
appKey string `json:"app_key"`
appSecret string `json:"app_secret"`
masterSecret string `json:"master_secret"`
token string `json:"token"`
expireTime string `json:"expire_time"`
locker sync.RWMutex
client *http.Client
config *platformapi.APIConfig
}
func NewUinappApi(appId, appKey, appSecret, masterSecret string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
curConfig = *config[0]
}
if appId == "" || masterSecret == "" {
return nil
}
return &API{
appId: appId,
appKey: appKey,
appSecret: appSecret,
masterSecret: masterSecret,
token: "",
expireTime: "",
locker: sync.RWMutex{},
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
}
func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
// 序列化
data, err := json.Marshal(bizParams)
if err != nil {
return nil, err
}
// 全路径请求参数
fullURL := utils.GenerateGetURL(baseUrl, actionApi, nil)
// 发送请求
sendUrl := func() *http.Request {
var request *http.Request
if http.MethodPost == method {
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data)))
} else {
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil)
}
if actionApi != GetTokenInterface {
request.Header.Set("token", a.token)
}
request.Header.Set("Content-Type", "application/json;charset=utf-8")
return request
}
// 数据解析
dataMarshal := func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
if err != nil {
return "", err
}
if utils.MustInterface2Int64(jsonResult1["code"]) != 200 {
errLevel = platformapi.ErrLevelGeneralFail
err = utils.NewErrorCode(jsonResult1["msg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["code"])))
}
retVal = jsonResult1
return errLevel, err
}
err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal)
return retVal, err
}
func (a *API) signParam(timestamp string) (sig string) {
sig = a.appKey + timestamp + a.masterSecret
signature := sha256.Sum256([]byte(sig))
return hex.EncodeToString(signature[:])
}
// GetUinAppToken 获取token
func (a *API) GetUinAppToken() error {
timestamp := utils.Int64ToStr(time.Now().UnixNano() / 1e6)
sign := a.signParam(timestamp)
result, err := a.AccessAPI(BaseUrl+a.appId, GetTokenInterface, http.MethodPost, map[string]interface{}{"timestamp": timestamp, "sign": sign, "appkey": a.appKey})
fmt.Println(err.Error())
if err != nil && !strings.Contains(err.Error(), "success") {
return err
}
var appToken *AppTokenRes
if err := utils.Map2StructByJson(result, &appToken, false); err != nil {
return err
}
if appToken.Code != 0 && appToken.Msg != "success" {
return errors.New(appToken.Msg)
}
a.token = appToken.Data.Token
a.expireTime = appToken.Data.ExpireTime
return nil
}
// CheckTokenIsExpire 校验头肯是否过期
// 注鉴权接口每分钟最大调用量为100次每天最大调用量为10万次建议开发者妥善管理token以免达到限制影响推送.感觉不做缓存也够用了!
func (a *API) CheckTokenIsExpire() (string, error) {
// 没有token或者token过期了
if a.token == "" || a.expireTime == "" || utils.Str2Int64(a.expireTime) < (time.Now().UnixNano()/1e6) {
a.GetUinAppToken()
return a.token, nil
}
return a.token, nil
}