From b6762f11ef88412cfddc388d78f664a746d05906 Mon Sep 17 00:00:00 2001 From: yangyl12345 Date: Mon, 25 Nov 2024 22:18:24 +0800 Subject: [PATCH 1/2] Update default_access_token.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 微信获取稳定版token,只有不等于空字符串的情况下才会返回access_token信息,未空的情况,继续调去微信服务 --- credential/default_access_token.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/credential/default_access_token.go b/credential/default_access_token.go index 00ad481..bcebb19 100644 --- a/credential/default_access_token.go +++ b/credential/default_access_token.go @@ -130,7 +130,9 @@ func (ak *StableAccessToken) GetAccessTokenContext(ctx context.Context) (accessT // 先从cache中取 accessTokenCacheKey := fmt.Sprintf("%s_stable_access_token_%s", ak.cacheKeyPrefix, ak.appID) if val := ak.cache.Get(accessTokenCacheKey); val != nil { - return val.(string), nil + if accessToken = val.(string); accessToken != "" { + return + } } // cache失效,从微信服务器获取 From a15ccac41eddddb82ca5edad744e851c32416274 Mon Sep 17 00:00:00 2001 From: w_yangyili Date: Tue, 26 Nov 2024 10:55:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E6=80=A7=E8=8E=B7=E5=8F=96=20access=5Ftoken=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E6=B7=BB=E5=8A=A0=E9=98=B2=E6=AD=A2=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E6=80=A7=E8=8E=B7=E5=8F=96=20access=5Ftoken=20?= =?UTF-8?q?=E5=92=8C=E5=A4=9A=E6=AC=A1=E5=BE=AE=E4=BF=A1=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- credential/default_access_token.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/credential/default_access_token.go b/credential/default_access_token.go index bcebb19..ec88a89 100644 --- a/credential/default_access_token.go +++ b/credential/default_access_token.go @@ -101,10 +101,11 @@ func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (access // 不强制更新access_token,可用于不同环境不同服务而不需要分布式锁以及公用缓存,避免access_token争抢 // https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html type StableAccessToken struct { - appID string - appSecret string - cacheKeyPrefix string - cache cache.Cache + appID string + appSecret string + cacheKeyPrefix string + cache cache.Cache + accessTokenLock *sync.Mutex } // NewStableAccessToken new StableAccessToken @@ -113,10 +114,11 @@ func NewStableAccessToken(appID, appSecret, cacheKeyPrefix string, cache cache.C panic("cache is need") } return &StableAccessToken{ - appID: appID, - appSecret: appSecret, - cache: cache, - cacheKeyPrefix: cacheKeyPrefix, + appID: appID, + appSecret: appSecret, + cache: cache, + cacheKeyPrefix: cacheKeyPrefix, + accessTokenLock: new(sync.Mutex), } } @@ -135,6 +137,17 @@ func (ak *StableAccessToken) GetAccessTokenContext(ctx context.Context) (accessT } } + // 加上lock,是为了防止在并发获取token时,cache刚好失效,导致从微信服务器上获取到不同token + ak.accessTokenLock.Lock() + defer ak.accessTokenLock.Unlock() + + // 双检,防止重复从微信服务器获取 + if val := ak.cache.Get(accessTokenCacheKey); val != nil { + if accessToken = val.(string); accessToken != "" { + return + } + } + // cache失效,从微信服务器获取 var resAccessToken ResAccessToken resAccessToken, err = ak.GetAccessTokenDirectly(ctx, false)