access_token是微信公眾號開發的全域唯一票據,公眾號開發必須要用到access_token。access_token的有效期間目前為2個小時,需定時重新整理,重複擷取將導致上次擷取的access_token失效。
access_token的請求次數是有限制的,所以不能每次都重新請求,只有將它緩衝到本地了。
function accessToken() { $tokenFile = "./access_token.txt";//快取檔案名 $data = json_decode(file_get_contents($tokenFile)); if ($data->expire_time < time() or !$data->expire_time) { $appid = "你的appid"; $appsecret = "你的appsecret"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret"; $res = getJson($url); $access_token = $res['access_token']; if($access_token) { $data['expire_time'] = time() + 7000; $data['access_token'] = $access_token; $fp = fopen($tokenFile, "w"); fwrite($fp, json_encode($data)); fclose($fp); } } else { $access_token = $data->access_token; } return $access_token; } //取得微信返回的JSON資料 function getJson($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); return json_decode($output, true);}
C#微信公眾平access_token的擷取儲存與更新
要解決的問題
1、如何擷取access_token。
2、由於access_token的有效期間為7200秒,即2小時,並且重複擷取將導致上次擷取的access_token失效,擷取access_token的api調用次數非常有限,所以要解決如何全域儲存與更新access_token。
思路
1、將access_token儲存在資料庫中。
2、何時更新access_token呢?當access_token失效的時候更新,那麼怎麼判斷access_token有沒有失效呢?使用當前的access_token請求微信介面,擷取自訂菜單,如果返回的errcode為42001,則說明access_token已經失效,這時再重新擷取access_token。
代碼:
1、Http請求代碼(HttpRequestUtil類):
#region 請求Url,不發送資料/// <summary>/// 請求Url,不發送資料/// </summary>public static string RequestUrl(string url){ return RequestUrl(url, "POST");}#endregion #region 請求Url,不發送資料/// <summary>/// 請求Url,不發送資料/// </summary>public static string RequestUrl(string url, string method){ // 設定參數 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; CookieContainer cookieContainer = new CookieContainer(); request.CookieContainer = cookieContainer; request.AllowAutoRedirect = true; request.Method = method; request.ContentType = "text/html"; request.Headers.Add("charset", "utf-8"); //發送請求並擷取相應回應資料 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程式才開始向目標網頁發送Post請求 Stream responseStream = response.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); //返回結果網頁(html)代碼 string content = sr.ReadToEnd(); return content;}#endregion
2、輔助方法(Tools類):
namespace SWX.Utils{ /// <summary> /// 工具類 /// </summary> public class Tools { #region 擷取Json字串某節點的值 /// <summary> /// 擷取Json字串某節點的值 /// </summary> public static string GetJsonValue(string jsonStr, string key) { string result = string.Empty; if (!string.IsNullOrEmpty(jsonStr)) { key = "\"" + key.Trim('"') + "\""; int index = jsonStr.IndexOf(key) + key.Length + 1; if (index > key.Length + 1) { //先截逗號,若是最後一個,截“}”號,取最小值 int end = jsonStr.IndexOf(',', index); if (end == -1) { end = jsonStr.IndexOf('}', index); } result = jsonStr.Substring(index, end - index); result = result.Trim(new char[] { '"', ' ', '\'' }); //過濾引號或空格 } } return result; } #endregion }}
3、判斷access_token是否到期(WXApi類):
#region 驗證Token是否到期/// <summary>/// 驗證Token是否到期/// </summary>public static bool TokenExpired(string access_token){ string jsonStr = HttpRequestUtil.RequestUrl(string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", access_token)); if (Tools.GetJsonValue(jsonStr, "errcode") == "42001") { return true; } return false;}#endregion
4、請求微信介面,擷取access_token(WXApi類):
#region 擷取Token/// <summary>/// 擷取Token/// </summary>public static string GetToken(string appid, string secret){ string strJson = HttpRequestUtil.RequestUrl(string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, secret)); return Tools.GetJsonValue(strJson, "access_token");}#endregion5、全域儲存與更新access_token(AdminUtil類): #region 擷取access_token/// <summary>/// 擷取access_token/// </summary>public static string GetAccessToken(PageBase page){ string access_token = string.Empty; UserInfo user = GetLoginUser(page); if (user != null) { if (string.IsNullOrWhiteSpace(user.access_token)) //尚未儲存過access_token { access_token = WXApi.GetToken(user.AppID, user.AppSecret); } else { if (WXApi.TokenExpired(user.access_token)) //access_token到期 { access_token = WXApi.GetToken(user.AppID, user.AppSecret); } else { return user.access_token; } } MSSQLHelper.ExecuteSql(string.Format("update SWX_Config set access_token='{0}' where UserName='{1}'", access_token, user.UserName)); } return access_token;}#endregion