获取AccessToken
今天主要介绍一下AccessToken的获取方式,这个是调用其他接口的基础。
首先看下微信开发文档上是如何定义AccessToken的。
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
公众平台的API调用所需的access_token的使用及生成方式说明:
1、为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器对外输出的依然是老access_token,此时公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
以上就是微信开发文档上内容,看完之后总结一下就是说了三点内容:
1、access_token很重要,是公众号的全局唯一票据,每次调用其他API的时候都要传这个参数。
2、2小时失效一次并且每日的总调用次数有上限,不能每次调用其他API都从新获取。
3、建议弄一个中控服务器来干获取这个事。
好,AccessToken是个什么玩意我们弄清楚了,接下来就要想如何获取它了。由于AccessToken取一次能用两小时且获取次数有上限这两个特点,我也参考了一些网上其他人的做法,总结了以下几种方式:
1、用单例模式写一个全局的访问方法来获取,获取之后放在内存中。调用时候判断一下上次取的时间差是不是大于两小时,如果大于就从取一次,如果不大于就直接返回上次取的值。
2、程序启动的时候启动一个线程定时取出AccessToken,然后存在本地xml或者数据库里。获取的时候直接从xml或者数据库里直接读取就行。
3、单独写一个程序来提供AccessToken。这是微信推荐的方式,在.net上其实就是写一个Windows服务或Wcf来干这个事。
我选的是第一种方式来做,开发比较简单而且容易理解。但是如果你需要把这个AccessToken保存下来的话也可以写到文件中或数据库里。第二种方式个人觉得不是很稳定,因为线程本身并不好控制。第三种是比较稳妥的方式,但比较麻烦,还要维护两个程序的运行状态。
下面是微信开发文档给出的接口调用及返回值说明:
下面的就是单例模式的类:
1 using Service.Common.Utility; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace Service.Wechat.Common 9 { 10 /* 单例模式 11 * 全局使用同一个Access_Token,每隔7200秒(2小时)微信服务器刷新一下 12 * 为了保证正常使用,程序每隔7000秒获取一次Access_Token 13 */ 14 public class AccessToken 15 { 16 private AccessToken() { } //私有化构造函数 17 public static readonly AccessToken Instance = new AccessToken(); //C#的单例模式 18 private string Access_Token = string.Empty; 19 private long last = 0; 20 public string GetAccessToken() 21 { 22 long Now = UtilityFunc.GetTimeStamp();//获取一个Unix时间戳 23 if(Now-last>7000) 24 { 25 var result = WeApiRequest.GetAccessToken(); 26 if (result.IsSuccess) 27 { 28 Access_Token = result.Info; 29 last = Now; 30 return Access_Token; 31 }else 32 { 33 return "err"; 34 } 35 36 } 37 else 38 { 39 return Access_Token; 40 } 41 } 42 } 43 }
这段是调用API的代码:
1 public static WeApiRequestResult GetAccessToken() 2 { 3 WeApiRequestResult result = new WeApiRequestResult() { IsSuccess = false, Info = string.Empty }; 4 string errMsg = string.Empty; 5 string appid = WeConst.AppID;//成为开发者时生成的AppID,在微信开发者中心里有 6 string secret = WeConst.AppSecret;//成为开发者时生成的AppSecret,在微信开发者中心里有 7 string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; 8 string requsetResult = HttpUtility.Request(HttpUtility.HTTP_GET, url, string.Empty, ref errMsg); 9 if (!string.IsNullOrEmpty(errMsg)) 10 { 11 WeLogger.Error("方法名:GetAccessToken(),请求Access_Token失败,错误信息:" + errMsg); 12 result.Info = errMsg; 13 return result; 14 } 15 string token = UtilityFunc.GetJsonValueByKey(requsetResult, "access_token"); 16 if (string.IsNullOrEmpty(token)) 17 { 18 WeLogger.Error("方法名:GetAccessToken(),请求Access_Token发送完成,但未取回Access_Token值,错误信息:" + requsetResult); 19 result.Info = requsetResult; 20 return result; 21 } 22 result.IsSuccess = true; 23 result.Info = token; 24 return result; 25 }
这段是所有调用接口方法的返回值类,就是上面那个方法的返回值类:
1 /// <summary> 2 /// 调用接口方法的返回值类 3 /// </summary> 4 public class WeApiRequestResult 5 { 6 public bool IsSuccess { get; set; } 7 public string Info { get; set; } 8 public object data { get; set; } 9 }
里面还有个http请求的方法和json操作的方法,各位小伙伴自己封装一下好,我就不在这里贴代码了,比较多。
总结一下:
总结获取AccessToken的三种方式,应该还有别的方式,小伙伴们如果还有其他方式也可以发邮件告诉我。cnryc@126.com。
第二种方式里的线程,可以写在Global.asax.cs文件的Application_Start()方法的最后。