您的位置:首页 > 微信 微信开发
站内搜索

微信开发

微信开发-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 + "&timestamp=" + 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中文网!

  • 上一篇:微信网页开发之创建Controller
  • 下一篇:微信报警 zabbix实现详解