token.go 2.4 KB
package yz

import (
	"context"
	"errors"
	"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
	Data *accessToken `json:"data"`
}

type accessToken struct {
	Expires     int64  `json:"expires"`
	Scope       string `json:"scope"`
	AccessToken string `json:"access_token"`
	AuthorityId string `json:"authority_id"`
}

// getAccessToken 获取token
func (s *client) getAccessToken(ctx context.Context) (err error) {
	var token *accessToken
	conn := g.Redis().Ctx(ctx).Conn()
	defer func() {
		_ = conn.Close()
	}()
	_, _ = conn.DoVar("SELECT", 10)
	cache, _ := conn.DoVar("HGETALL", CacheKey)
	if !cache.IsEmpty() {
		_ = cache.Scan(&token)
		if token.Expires > gtime.TimestampMilli() {
			s.AccessToken = token.AccessToken
			return
		}
		return s.refreshToken(ctx, token)
	}
	var params = g.Map{
		"client_id":      s.AppKey,
		"client_secret":  s.AppSecret,
		"authorize_type": authorizeType,
		"grant_id":       s.GrantId,
		"refresh":        false,
	}

	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.Message)
		return
	}
	_, _ = conn.Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Data))...)...)
	s.AccessToken = jdRes.Data.AccessToken
	return
}

// refreshToken 刷新token
func (s *client) refreshToken(ctx context.Context, req *accessToken) (err error) {
	_, err = g.Redis().DoVar("DEL", CacheKey)

	var params = g.Map{
		"client_id":      s.AppKey,
		"client_secret":  s.AppSecret,
		"authorize_type": "silent",
		"grant_id":       s.GrantId,
		"refresh":        true,
	}
	result, err := s.post(ctx, s.GetTokenUrl, params)
	if err != nil {
		return
	}
	var jdRes *getAccessTokenRes
	err = gjson.New(result).Scan(&jdRes)
	if err != nil {
		return
	}
	if jdRes == nil {
		return
	}
	if !jdRes.Success {
		err = errors.New(jdRes.Message)
		return
	}
	conn := g.Redis().Ctx(ctx).Conn()
	defer func() {
		_ = conn.Close()
	}()
	_, _ = conn.DoVar("SELECT", 10)
	_, _ = conn.Do("HMSET", append(g.Slice{CacheKey}, gutil.MapToSlice(gconv.Map(jdRes.Data))...)...)
	s.AccessToken = jdRes.Data.AccessToken
	return
}