擷取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的重新整理流程。
公衆号和小程式均可以使用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 | 系統繁忙,此時請開發者稍候再試 |
請求成功 | |
40001 | AppSecret錯誤或者AppSecret不屬于這個公衆号,請開發者确認AppSecret的正确性 |
40002 | 請確定grant_type字段值為client_credential |
40164 | 調用接口的IP位址不在白名單中,請在接口IP白名單中進行設定。(小程式及小遊戲調用不要求IP位址在白名單内。) |
示例代碼:
//建立 Access_token類
public class Access_token
{
public string access_token { get; set; }
public string expires_in { get; set; }
}
再将access_token做緩存,建立一個XML檔案存儲(或存儲在資料庫中,根據自己的程式設計愛好),XML格式如下:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<Access_Token>第一次可以随便寫</Access_Token>
<Access_YouXRQ>2016/2/21 20:15:49</Access_YouXRQ>
</xml>
剛建好的XML,Access_Token節點中的資料可以随便寫,Access_YouXRQ節點中的資料寫一個之前兩小時的時間就可以了(推薦直接寫前一天的23:59:59)
擷取的邏輯是:當需要用到Access_Token的時候,直接調用IsExistAccess_Token()方法即可,以下是IsExistAccess_Token()方法實作的代碼:
/// <summary>
/// 根據目前日期 判斷Access_Token 是否超期 如果超期傳回新的Access_Token 否則傳回之前的Access_Token
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
private static string IsExistAccess_Token()
{
string Token = string.Empty;
DateTime YouXRQ;
// 讀取XML檔案中的資料,并顯示出來 ,注意檔案路徑
string filepath = HttpContext.Current.Server.MapPath(".") + "\\AccessToken.xml";
StreamReader str = new StreamReader(filepath, Encoding.UTF8);
XmlDocument xml = new XmlDocument();
xml.Load(str);
str.Close();
str.Dispose();
Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText;
YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText);
//TimeSpan st1 = new TimeSpan(YouXRQ.Ticks); //最後重新整理的時間
//TimeSpan st2 = new TimeSpan(DateTime.Now.Ticks); //目前時間
//TimeSpan st = st2 - st1; //兩者相差時間
if (DateTime.Now > YouXRQ)
{
DateTime _youxrq = DateTime.Now;
Access_token mode = GetAccess_token();
xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.access_token;
_youxrq = _youxrq.AddSeconds(int.Parse(mode.expires_in));
xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString();
xml.Save(filepath);
Token = mode.access_token;
}
return Token;
}
/// <summary>
/// 擷取Access_token
/// </summary>
/// <returns></returns>
private static Access_token GetAccess_token()
{
string appid = "你自己微信公衆測試号的appID"; //微信公衆号appid
string secret = "你自己微信公衆測試号的appsecret"; //微信公衆号appsecret
string strUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
Access_token mode = new Access_token();
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(strUrl); //用GET形式請求指定的位址
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
//HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(wr.GetResponseStream(), Encoding.UTF8);
string content = reader.ReadToEnd();
reader.Close();
reader.Dispose();
//在這裡對Access_token 指派
Access_token token = new Access_token();
token = JsonHelper.ParseFromJson<Access_token>(content);
mode.access_token = token.access_token;
mode.expires_in = token.expires_in;
}
return mode;
}
可以看出來上面的GetAccess_token()方法裡面使用了JsonHelper類,這個類可以在網上下載下傳,也可以自己寫,下面是我自己寫的JsonHelper類供參考:
public class JsonHelper
{
/// <summary>
/// 生成Json格式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string GetJson<T>(T obj)
{
DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
using (MemoryStream stream = new MemoryStream())
{
json.WriteObject(stream, obj);
string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson;
}
}
/// <summary>
/// 擷取Json的Model
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="szJson"></param>
/// <returns></returns>
public static T ParseFromJson<T>(string szJson)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
return (T)serializer.ReadObject(ms);
}
}
}
至此就可以生成帶緩存功能的Access_Token,調用的時候string token=IsExistAccess_Token();