微信access_token和refresh_token保存於redis


簡介

  • 通常理解的access_token和refresh_token
    • access_token是用來對客戶端進行認證的,類似與密碼,有一定的有效期。當過期后可使用refresh_token重新獲取一個新的access_token。refresh_token的有效期相對較長
  • 微信開發設置到兩種access_token
    • 第一種是接口授權access_token,是用來調用微信高級接口的,有次數限制,是來區分公眾號的
    • 另外一種是用戶授權access_token,是用戶授權公眾號獲取用戶信息是得到的,無次數限制,使用用來區分用戶的(一般用在微信H5開發上)
  • 由於上述第一種access_token是有次數限制的,因此我們需要將太緩存(保存)起來,每次調用接口的時候先取我們緩存的access_token,而不是從新獲取一個新的access_token。
  • 由於refresh_token的有效期相對較長,且使用頻率較少,此處只說明access_token的保存(refresh_token可類似處理)

使用redis保存access_token

  • 微信公眾平台API每日有調用上限,即使某些公眾號或服務號有清零某些接口調用的次數權限,但也架不住濫用或錯誤的調用,官方建議access_token由一台服務來維護和提供查詢功能,另外特別重要的一點是每個憑證都擁有生命周期,長短不同,access_token的生命周期是7200秒,在這段時間內可以重復使用,所以不要在每使用一次憑證就重新獲取一個access_token了。
  • 通常會保存在內存數據庫中,如Redis,當然也可以直接放在應用程序的內存中,不建議放在oracle或MySQL,拿取開銷較比其它手段太重。放在內存數據庫中的好處較比放在應用程序的內存中是維護性好,尤其是搭配了可視化管理工具后。另外不僅可以放access_token,也可以其它數據庫。[^1] [^2]
  • 示例(基於springboot)

    • redis等其他基礎配置省略

    • application.yml 其中myapp下的key都需要進行自定義參數配置,此處也存儲了用戶授權access_token

      myapp:
          redisWxUserAccessToken: "user.wxUserAccessToken"
          redisWxUserRefreshToken: "user.wxUserRefreshToken"
          redisWxAccessToken: "sys.wxAccessToken"
          redisWxRefreshToken: "sys.wxRefreshToken"
      
    • 此處以保存用戶授權access_token為例,接口調用access_token可在項目啟動時進行緩存。部分代碼如下:

      @Autowired
      private RedisTemplate<String, String> redisTemplate;
      
      @Value("${myapp.redisWxUserAccessToken}")
      private String redisWxUserAccessToken;
      
      // 獲取
      public String getUserAccessToken(Object userId) {
          String accessToken = null;
          if(StringUtils.isEmpty(userId)) return accessToken;
      
          String accessTokenStr = (String) redisTemplate.opsForHash().get(redisWxUserAccessToken, String.valueOf(userId));
          long now = (new Date()).getTime();
          if(!StringUtils.isEmpty(accessTokenStr)) {
              String[] arr = accessTokenStr.split("#");
      
              if(now < Long.valueOf(arr[1])) {
                  accessToken = arr[0];
              }
          }
      
          if(StringUtils.isEmpty(accessToken)) {
              accessToken = getUserAccessTokenByRefreshToken(userId);
          }
      
          return accessToken;
      }
      
      
      // 重新獲取
      Object expiresIn = accessTokenMap.get("expires_in"); // 調用微信授權接口后,返回的expires_in參數
      String value = accessTokenNew + "#" + getNowExpiresIn(expiresIn); // 此處是設置有效期
      redisTemplate.opsForHash().put(redisWxUserAccessToken, String.valueOf(userId), value);
      
      
      public Long getNowExpiresIn(Object expiresIn) {
          long now = (new Date()).getTime();
          if(expiresIn == null) return now;
      
          Long expiresMs = Long.valueOf(String.valueOf(expiresIn)) - 15 * 60;
          return expiresMs * 1000 + now;
      }
      

[^1] 網頁授權的access_token大家是怎么緩存的
[^2] https://segmentfault.com/q/1010000004995599/a-1020000005016398


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM