微信开发-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}

时间: 2024-08-27 20:28:41

微信开发-ACCESS TOKEN 过期失效解决方案的相关文章

微信公众号开发Access Token

Access Token 在微信公众平台接口开发中,Access Token占据了一个很重要的地位,相当于进入各种接口的钥匙,拿到这个钥匙才有调用其他各种特殊接口的权限. access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效. 公众号可以使用AppID和AppSecret调用本接口来获取access_token.AppID和AppSecret可

nodejs微信开发获取token,ticket-1

1 /* jshint -W079 */ 2 /* jshint -W020 */ 3 4 "use strict"; 5 var _ = require("lodash"); 6 var sha1 = require('sha1'); 7 var urlencode = require('urlencode'); 8 var request = require('request'); 9 var express = require('express'); 10 v

atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制

atitit. access token是什么??微信平台公众号开发access_token and Web session保持状态机制 1. token机制and  session保持状态机制 1 2. access token是什么?? 1 3. 为什么需要access token 2 4. 需不需要保存access_token,如何保存??? 2 5. access_token在何时被创建 2 6. 为什么不直接使用appid保持状态 2 7. access_token的过期问题 3 8.

Force.com微信开发系列(四)申请Access Token及自定义菜单之创建菜单

在微信接口开发中,许多服务的使用都离不开Access Token,Access Token相当于打开这些服务的钥匙,正常情况下会在7200秒内失效,重复获取将导致上次获取的Token失效,本文将首先介绍如何获取Access Token,再介绍如何通过Access Token来在微信内添加自定义菜单(注意,开发者需要申请测试账号来测试自定义菜单,如何申请请参照前文). 申请Access Token 获取Access Token接口的网址如下: https://api.weixin.qq.com/c

微信公众平台开发学习笔记2--获取access token

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.获取的access_token过期时间为2小时.获取access token具体说明请参考官方文档. 我们不能因为每个业务要用到access_token的时候,都去微信服务器去请求获取新的access_token,所以我们要把获取到的access_token进行保存. 解决问题的大体思路如下: 我们将获取到的access_token码,和调用微信接口时的时间保存到数据库,或者记录到xml中,每次要

微信公众平台开发 获取access token (续)

直接上代码: 关键代码 第一步 /** * @author  lizhe * */public class WxAccessToken {    private String token;    private int expiresIn;    public String getToken() {        return token;    }    public void setToken(String token) {        this.token = token;    }  

使用缓存Memcache存储更新微信access token

关键字:Memcache access_token 更新 存储 7200 本文介绍如何使用缓存Memcache存储及更新 access token的方法. 一.Access Token access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效. 公众号可以使用AppID和AppSecret调用本接口来获取access_token.AppID和App

微信公众平台开发问题——token验证失败

之前学了PHP后做的平台的开发,token验证是成功的,昨晚手贱改了一下聊天机器人的url和token之后,感觉没小黄鸡好玩,就改了回来,一改就是一晚上.而且昨晚微信开发者的那个后台基本登不上去,一直的token错误. define("TOKEN", "weixin"); 明明就是weixin这样的token常量. 早上,发现: 原来还有一层文件夹. 这样,我的url就有错了. 应该是http://1.zhongkaixyt.sinaapp.com/zkxyt/ma

PHP CURL获取微信公众平台的ACCESS TOKEN以及创建菜单的方法

//使用curl模块,必须在php.in 里面将curl模块开启.<?php header("Content-type: text/html; charset=utf-8"); define("app_id","xxx");//APP_ID define("app_secret","xxxx");//APP_SECRET //获取access token 的方法 function get_access