微信开发-ACCESS TOKEN 过期失效解决方案
微信开发-ACCESS TOKEN 过期失效解决方案
起因:因为access_token的重要性,开发过微信的都知道,但是他有自己的生命周期,官方解释为:"有效期为7200秒",一天调用2000次。流量一高,就over了,没办法,龙哥不帮我们解决问题,我们就要自己解决,不能等死。
解决思路很简单:建立公共access token数据,有效期内不重新创建access_token。
解决方案:1、微信类库:有效期内直接读取access token数据文件中的json数据,过期失效,重新获取并创建新的access token数据文件2、数据文件:存放有效的access token数据,具体有:access_token.json和jsapi_ticket.json
核心代码如下:Index: wxjsSDK.cs===================================================================--- wxjsSDK.cs(revision 0)+++ wxjsSDK.cs(revision 1)@@ -0,0 +1,209 @@+using System;+using System.Collections.Generic;+using System.Web;+using System.IO;+using System.Security.Cryptography;+using System.Runtime.Serialization.Json;+using System.Runtime.Serialization;+using System.Net;+using System.Runtime.Serialization.Formatters.Binary;+using System.Text; ++namespace JR.Common+{+public class wxjsSDK+{+private string appId; +private string appSecret;+++public wxjsSDK(string appId, string appSecret) +{ +this.appId = appId; +this.appSecret = appSecret; +} ++++//得到数据包,返回使用页面 +public System.Collections.Hashtable getSignPackage() +{ +string jsapiTicket = getJsApiTicket(); +string url = HttpContext.Current.Request.Url.ToString(); //"http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; +string timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now)); +string nonceStr = createNonceStr(); +// 这里参数的顺序要按照 key 值 ASCII 码升序排序 +string rawstring = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url + ""; +string signature = SHA1_Hash(rawstring); +var signPackage = new System.Collections.Hashtable(); +signPackage.Add("appId", appId); +signPackage.Add("nonceStr", nonceStr); +signPackage.Add("timestamp", timestamp); +signPackage.Add("url", url); +signPackage.Add("signature", signature); +signPackage.Add("rawString", rawstring); +return signPackage; +} +++//创建随机字符串 +private string createNonceStr()+{+int length = 16;+string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";+string str = "";+var rad = new Random();+for (int i = 0; i < length; i++)+{+str += chars.Substring(rad.Next(0, chars.Length - 1), 1);+}+return str;+}+++//得到ticket 如果文件里时间 超时则重新获取 +private string getJsApiTicket()+{+string ticket = "";+// jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 +string path = HttpContext.Current.Server.MapPath(@"/log/jssdk/jsapi_ticket.json");+if (!File.Exists(path))+{+File.Create(path).Close();+}+StreamReader sr = new StreamReader(path, System.Text.Encoding.Default);+string filecontent = sr.ReadToEnd();+CommonJsonModel jsonModel = null;+if (!string.IsNullOrEmpty(filecontent))+{+jsonModel = new CommonJsonModel(filecontent);+}+sr.Close();+sr.Dispose();+if (jsonModel == null || int.Parse(jsonModel.GetValue("expires_in")) < ConvertDateTimeInt(DateTime.Now))+{+string accessToken = getAccessToken();+string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken;+jsonModel = new CommonJsonModel(httpGet(url));+ticket = jsonModel.GetValue("ticket");+if (ticket != "")+{+string json = "{"ticket":"" + ticket + "","expires_in":" + (ConvertDateTimeInt(DateTime.Now) + 7000) + "}";+StreamWriterMetod(json, path);+}+}+else+{+ticket = jsonModel.GetValue("ticket");+}+return ticket;+}+++//得到accesstoken 如果文件里时间 超时则重新获取 +private string getAccessToken()+{+// access_token 应该全局存储与更新,以下代码以写入到文件中做示例 +string access_token = "";+string path = HttpContext.Current.Server.MapPath(@"/log/jssdk/access_token.json");+if (!File.Exists(path))+{+File.Create(path).Close();+}+StreamReader sr = new StreamReader(path, System.Text.Encoding.Default);+string filecontent = sr.ReadToEnd();+CommonJsonModel jsonModel = null;+if (!string.IsNullOrEmpty(filecontent))+{+jsonModel = new CommonJsonModel(filecontent);+}+sr.Close();+sr.Dispose();+if (jsonModel == null || int.Parse(jsonModel.GetValue("expires_in")) < ConvertDateTimeInt(DateTime.Now))+{+string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId ++"&secret=" + appSecret + "";+jsonModel = new CommonJsonModel(httpGet(url));+access_token = jsonModel.GetValue("access_token");+if (access_token != "")+{+string json = "{"access_token":"" + access_token + "","expires_in":" + (ConvertDateTimeInt(DateTime.Now) + 7000) + "}";+StreamWriterMetod(json, path);+}+}+else+{+access_token = jsonModel.GetValue("access_token");+}+return access_token;+}+++//发起一个http请球,返回值 +private string httpGet(string url) +{+try+{+var MyWebClient = new WebClient();+MyWebClient.Credentials = CredentialCache.DefaultCredentials; //获取或设置用于向Internet资源的请求进行身份验证的网络凭据 +Byte[] pageData = MyWebClient.DownloadData(url); //从指定网站下载数据 +string pageHtml = System.Text.Encoding.Default.GetString(pageData);//如果获取网站页面采用的是GB2312,则使用这句+//string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8,则使用这句 +return pageHtml;+}+catch (WebException webEx)+{+Console.WriteLine(webEx.Message.ToString());+return null;+}+} +++//SHA1哈希加密算法 +private string SHA1_Hash(string str_sha1_in) +{ +SHA1 sha1 = new SHA1CryptoServiceProvider(); +byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str_sha1_in); +byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in); +string str_sha1_out = BitConverter.ToString(bytes_sha1_out); +str_sha1_out = str_sha1_out.Replace("-", "").ToLower(); +return str_sha1_out; +} +++/// <summary> +/// StreamWriter写入文件方法 +/// </summary> +private void StreamWriterMetod(string str, string patch) +{+FileStream stream = new FileStream(patch, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);+StreamWriter writer = new StreamWriter(stream);+writer.WriteLine(str);+stream.Flush();+writer.Close();+stream.Close();+stream.Dispose();+writer.Dispose();+} +++++/// <summary> +/// 将c# DateTime时间格式转换为Unix时间戳格式 +/// </summary> +/// <param name="time">时间</param> +/// <returns>double</returns> +private int ConvertDateTimeInt(System.DateTime time) +{ +int intResult = 0; +System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); +intResult = Convert.ToInt32((time - startTime).TotalSeconds); +return intResult; +} +++}+++}access_token.json{"access_token":"4H14BVCUrAxxxxxxxxxxxxWeLu-zKETaBYqsoKFjsHZDc3xOwc-m43WDw2HjzxEkng2nC7iJuHydNt5PqRDY7HCoAU4lmuaPoYsIQHdW9kA","expire_time":1428599121}access_token.json{"jsapi_ticket":"bxLdikRXVbTPdHSM05e5u1wgoccccccccccccccccccccccccccccc11FFzYsiqbXZN0SDGN6Dnksnt2Q","expire_time":1428599122}更多微信开发-ACCESS TOKEN 过期失效解决方案 相关文章请关注PHP中文网!