5. (全局唯一接口調用憑據)獲取Access token


 

一.官方文檔說明

access_token是公眾號的全局唯一接口調用憑據,公眾號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。

公眾平台的API調用所需的access_token的使用及生成方式說明:

1、建議公眾號開發者使用中控服務器統一獲取和刷新access_token,其他業務邏輯服務器所使用的access_token均來自於該中控服務器,不應該各自去刷新,否則容易造成沖突,導致access_token覆蓋而影響業務;

2、目前access_token的有效期通過返回的expire_in來傳達,目前是7200秒之內的值。中控服務器需要根據這個有效時間提前去刷新新access_token。在刷新過程中,中控服務器可對外繼續輸出的老access_token,此時公眾平台后台會保證在5分鍾內,新老access_token都可用,這保證了第三方業務的平滑過渡;

3、access_token的有效時間可能會在未來有調整,所以中控服務器不僅需要內部定時主動刷新,還需要提供被動刷新access_token的接口,這樣便於業務服務器在API調用獲知access_token已超時的情況下,可以觸發access_token的刷新流程。

4、對於可能存在風險的調用,在開發者進行獲取 access_token調用時進入風險調用確認流程,需要用戶管理員確認后才可以成功獲取。具體流程為:

開發者通過某IP發起調用->平台返回錯誤碼[89503]並同時下發模板消息給公眾號管理員->公眾號管理員確認該IP可以調用->開發者使用該IP再次發起調用->調用成功。

如公眾號管理員第一次拒絕該IP調用,用戶在1個小時內將無法使用該IP再次發起調用,如公眾號管理員多次拒絕該IP調用,該IP將可能長期無法發起調用。平台建議開發者在發起調用前主動與管理員溝通確認調用需求,或請求管理員開啟IP白名單功能並將該IP加入IP白名單列表。

公眾號和小程序均可以使用AppID和AppSecret調用本接口來獲取access_token。AppID和AppSecret可在“微信公眾平台-開發-基本配置”頁中獲得(需要已經成為開發者,且帳號沒有異常狀態)。**調用接口時,請登錄“微信公眾平台-開發-基本配置”提前將服務器IP地址添加到IP白名單中,點擊查看設置方法,否則將無法調用成功。**小程序無需配置IP白名單。

接口調用請求說明

https請求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

參數說明

參數 是否必須 說明
grant_type 獲取access_token填寫client_credential
appid 第三方用戶唯一憑證
secret 第三方用戶唯一憑證密鑰,即appsecret

返回說明

正常情況下,微信會返回下述JSON數據包給公眾號:

{"access_token":"ACCESS_TOKEN","expires_in":7200} 

 

返回參數說明

參數 說明
access_token 獲取到的憑證
expires_in 憑證有效時間,單位:秒

錯誤時微信會返回錯誤碼等信息,JSON數據包示例如下(該示例為AppID無效錯誤):

{"errcode":40013,"errmsg":"invalid appid"} 

返回碼說明

返回碼 說明
-1 系統繁忙,此時請開發者稍候再試
0 請求成功
40001 AppSecret錯誤或者AppSecret不屬於這個公眾號,請開發者確認AppSecret的正確性
40002 請確保grant_type字段值為client_credential
40164 調用接口的IP地址不在白名單中,請在接口IP白名單中進行設置。(小程序及小游戲調用不要求IP地址在白名單內。)
89503 此IP調用需要管理員確認,請聯系管理員
89501 此IP正在等待管理員確認,請聯系管理員
89506 24小時內該IP被管理員拒絕調用兩次,24小時內不可再使用該IP調用
89507 1小時內該IP被管理員拒絕調用一次,1小時內不可再使用該IP調用

 

二 .代碼實現

2.1 創建一個對象,分別對應返回結果和過期時間,過期時間通過獲取的有效時間和當前時間計算出,具體如下:

package com.grand.weichat.entity;

public class AccessToken {
	private String accessToken;
	private Long expireTime;//過期時間
	
	public AccessToken(String accessToken, String expireIn) {
		super();
		this.accessToken = accessToken;
		//計算出過期時間,當前時間加返回的有效時間7200秒(兩小時)
		expireTime=System.currentTimeMillis()+Integer.parseInt(expireIn)*1000;
	}
	public String getAccessToken() {
		return accessToken;
	}
	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}
	public Long getExpireTime() {
		return expireTime;
	}
	public void setExpireTime(Long expireTime) {
		this.expireTime = expireTime;
	}
	
	//判斷token是否過期
	public boolean isExpired() {
		//如果當前時間大於有效時間,則過期
		return System.currentTimeMillis()>expireTime;
	}

}

  

 

2.2 前面文檔官方文檔中有提到不應該各自去刷新,否則容易造成沖突,導致access_token覆蓋而影響業務;

2.3  所以需編寫方法getAccessToken根據傳入的appId和appSecret獲取保證每次都能獲取到有效的Access_token,完整代碼如下:

package com.grand.weichat.util.base;

import com.grand.weichat.entity.AccessToken;
import net.sf.json.JSONObject;
import cn.hutool.http.HttpUtil;
import lombok.extern.log4j.Log4j;

/**
 * 解析XML文件
 */
@Log4j
public class WXUtilsCenter {

	//token獲取地址
	private static final String GET_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";


	//存貯token和有效時間
	private static AccessToken at;



	/**
	 * 更新access_token與有效的時間信息
	 * @return true成功,failed失敗
	 */
	private static boolean getToken(String appId,String appSecret){
		String url=GET_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret);
		String strToken=null;
		try {
			strToken = HttpUtil.get(url);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		if(strToken!=null) {
			JSONObject json=JSONObject.fromObject(strToken);
			String token=json.getString("access_token");//token
			String expirexIn=json.getString("expires_in");//有效時間
			//創建token並存起來
			at=new AccessToken(token, expirexIn);
		}
		return true;
	}
	//向外暴露獲取token的方法
	public static String getAccessToken(String appId,String appSecret) {
		//token失效則重新獲取
		if(at==null || at.isExpired()) {
			boolean tokenboo=getToken(appId,appSecret);
			if(!tokenboo) {
				log.info("更新access_token失敗");
			}
		}
		return at.getAccessToken();
	}

}

  

2.4  這樣后續獲取access_token的時候就不會造成各自刷新的沖突,每次的使用都會是同一個access_token

 


免責聲明!

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



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