微信开发中 ACCESS TOKEN 过期失效的解决方案详解

why 104 2024-09-10

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

核心代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

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}



版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序利用 JS 实现注册 60s 倒计时功能解析
下一篇:微信小程序选项卡功能开发步骤与方法全解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~