jingdong_token.go 2.6 KB
package jingdong

import (
	"context"
	"errors"
	"github.com/gogf/gf/crypto/gmd5"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/util/gconv"
	"github.com/gogf/gf/util/gutil"
)

type getAccessTokenRes struct {
	*CommonRes
	Result *accessToken `json:"result"`
}

type refreshTokenRes struct {
	*CommonRes
	Result *accessToken `json:"result"`
}

type accessToken struct {
	Uid                 string `json:"uid"`
	AccessToken         string `json:"access_token"`
	RefreshToken        string `json:"refresh_token"`
	Time                int64  `json:"time"`
	ExpiresIn           int64  `json:"expires_in"`
	RefreshTokenExpires int64  `json:"refresh_token_expires"`
}

//getAccessToken 获取token
func (s *client) getAccessToken(ctx context.Context) (err error) {
	var token *accessToken
	cache, _ := g.Redis().DoVar("HGETALL", CacheKey)
	if !cache.IsEmpty() {
		_ = cache.Scan(&token)
		if token.Time+token.ExpiresIn*1000 > gtime.TimestampMilli() {
			s.AccessToken = token.AccessToken
			return
		}
		return s.refreshToken(ctx, token)
	}
	timeStamp := gtime.Now().String()
	sign := s.getSign(timeStamp)
	var params = g.Map{
		"grant_type": "access_token",
		"client_id":  s.AppKey,
		"timestamp":  timeStamp,
		"username":   server.UserName,
		"password":   gmd5.MustEncrypt(s.PassWord),
		"sign":       sign,
	}

	result, err := s.post(ctx, server.GetTokenUrl, params)
	if err != nil {
		return
	}

	var jdRes *getAccessTokenRes
	_ = gjson.New(result).Scan(&jdRes)
	if jdRes == nil {
		err = errors.New("authorize failed,empty response")
		return
	}

	if !jdRes.Success {
		err = errors.New(jdRes.ResultMessage)
		return
	}
	_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
	s.AccessToken = jdRes.Result.AccessToken
	return
}

//refreshToken 刷新token
func (s *client) refreshToken(ctx context.Context, req *accessToken) (err error) {
	if req.RefreshTokenExpires < gtime.Timestamp() {
		_, err = g.Redis().DoVar("DEL", CacheKey)
		return s.getAccessToken(ctx)
	}
	var params = g.Map{
		"refresh_token": req.RefreshToken,
		"client_id":     s.AppKey,
		"client_secret": s.AppSecret,
	}
	result, err := s.post(ctx, s.RefreshTokenUrl, params)
	if err != nil {
		return
	}
	var jdRes *refreshTokenRes
	err = gjson.New(result).Scan(&jdRes)
	if err != nil {
		return
	}
	if jdRes == nil {
		return
	}
	if !jdRes.Success {
		err = errors.New(jdRes.ResultMessage)
		return
	}
	_, _ = g.Redis().Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Result))...)...)
	s.AccessToken = jdRes.Result.AccessToken
	return
}