PHP accesstoken失效,微信开发-ACCESS TOKEN 过期失效解决方案

本文介绍了解决微信开发中ACCESS_TOKEN过期问题的方法,通过缓存策略确保在有效期内重用token,同时展示了如何读取和更新access_token和jsapi_ticket的数据文件。

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

+ }

+

+

+ ///

+ /// StreamWriter写入文件方法

+ ///

+ 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();

+ }

+

+

+

+

+ ///

+ /// 将c# DateTime时间格式转换为Unix时间戳格式

+ ///

+ /// 时间

+ /// double

+ 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中文网!

相关标签:微信开发

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

<think>我们正在讨论如何配置企业微信JS-SDK的签名参数。根据引用内容,签名配置需要后端服务计算生成,然后在前端调用wx.config方法。以下是详细步骤: ### 一、签名参数配置流程 1. **获取企业信息**: - `corpId`:企业ID(企业微信管理后台查看) - `agentId`:应用ID(企业微信后台应用详情页获取- `secret`:应用密钥(企业微信后台应用详情页获取) 2. **服务端生成签名步骤**: ```mermaid graph TD A[获取当前页面URL] --> B[生成随机字符串noncestr] B --> C[获取当前时间戳timestamp] C --> D[获取access_token] D --> E[获取jsapi_ticket] E --> F[拼接签名串] F --> G[计算sha1签名] ``` 3. **签名算法实现(Node.js示例)**: ```javascript const crypto = require('crypto'); function getSignature(jsapi_ticket, noncestr, timestamp, url) { const string = `jsapi_ticket=${jsapi_ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}`; return crypto.createHash('sha1').update(string).digest('hex'); } ``` ### 二、前端配置代码模板 ```javascript wx.config({ beta: true, // 必须开启beta模式 debug: false, // 调试模式 appId: '企业ID', // corpId timestamp: 1620000000, // 时间戳(秒级) nonceStr: '随机字符串', // 16-32位 signature: '服务端计算的签名', jsApiList: [ 'downloadFile', 'openDocument', 'scanQRCode' // 按需添加API ], success: () => console.log('SDK配置成功'), fail: (err) => console.error('SDK配置失败', err) }); ``` ### 三、关键注意事项 1. **URL处理规则**: - 必须与前端页面URL完全一致(包括#hash部分) - 需使用`encodeURIComponent`处理特殊字符 - 示例: ```javascript // 前端获取当前URL(不含#后的参数) const url = encodeURIComponent(window.location.href.split('#')[0]); ``` 2. **签名有效期**: - `jsapi_ticket` 有效期7200秒,需缓存(避免频繁请求) - 时间戳误差需在10分钟内 3. **常见错误码**: | 错误码 | 原因 | 解决方案 | |--------|---------------------|-------------------------| | 40001 | 密钥错误 | 检查`secret`是否正确 | | 40014 | `access_token`失效 | 重新获取`access_token` | | 40091 | `jsapi_ticket`失效 | 刷新`jsapi_ticket` | > 详细错误参考[官方文档](https://work.weixin.qq.com/api/doc/90000/90136/90506)[^1] ### 四、企业微信后台配置要求 1. **可信域名设置**: - 登录企业微信管理后台 - 进入「应用管理」→ 选择应用 → 设置可信域名 - 上传验证文件至域名根目录 2. **IP白名单(仅限第三方应用)**: - 服务端出口IP需加入企业微信白名单 - 路径:管理后台 → 开发者接口 → IP白名单 > 配置完成后需等待10分钟生效[^2] ### 五、签名验证工具 企业微信提供官方调试工具: ```markdown [在线签名校验工具](https://work.weixin.qq.com/api/jsapisign) ``` 通过该工具可验证签名算法是否正确[^3]。 §§相关问题§§ 1. 如何获取企业微信的jsapi_ticket? 2. 企业微信JS-SDK初始化失败如何排查? 3. 企业微信可信域名验证文件如何配置? </think> ### 企业微信JS-SDK签名参数配置方法 以下是完整的签名参数配置流程(需前后端协作): #### 一、核心签名参数说明 | 参数 | 说明 | 获取方式 | |--------------|------------------------------|----------------------------------| | `corpId` | 企业ID(固定值) | 企业微信管理后台→我的企业→企业ID | | `agentId` | 应用唯一标识 | 应用管理→选择应用→AgentId | | `timestamp` | 当前时间戳(秒级) | 服务端生成:`Math.floor(Date.now()/1000)` | | `nonceStr` | 随机字符串(16-32字符) | 服务端生成(建议UUID) | | `signature` | 加密签名 | 服务端通过算法生成 | | `jsApiList` | 需调用的API列表 | 如:`['downloadFile','openDocument']` | #### 二、服务端签名生成步骤(Java示例) ```java // 1. 获取access_token(每日限2000次) String accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId + "&corpsecret=" + secret; // 返回示例: {"access_token": "xxx", "expires_in": 7200} // 2. 获取jsapi_ticket String ticketUrl = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + accessToken; // 返回示例: {"ticket": "xxx", "expires_in": 7200} // 3. 生成签名 public String generateSignature(String ticket, String noncestr, long timestamp, String url) { String plain = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; // 当前页面完整URL return sha1(plain); // SHA1加密 } ``` #### 三、前端配置代码 ```javascript // 从服务端获取签名配置(示例用axios) axios.get('/api/wechat-signature?url=' + encodeURIComponent(window.location.href)) .then(response => { const { corpId, agentId, timestamp, nonceStr, signature } = response.data; wx.config({ beta: true, // 必须开启!否则无法调用downloadFile等API debug: false, // 调试模式 appId: corpId, // 注意:这里填企业ID timestamp: timestamp, nonceStr: nonceStr, signature: signature, jsApiList: ['downloadFile', 'openDocument'] // 按需声明API }); wx.ready(() => { console.log("SDK配置成功!"); }); wx.error(err => { console.error("SDK配置失败:", err); }); }); ``` #### 四、关键注意事项 1. **URL一致性原则** 前端传递的URL(`window.location.href`)必须与后端计算签名的URL**完全一致**,需注意: - 移除URL中的`#`及之后的部分 - 编码特殊字符:`encodeURIComponent()` - 禁止动态修改URL参数 2. **签名时效性** ```mermaid graph LR A[生成签名] -->|有效期| B(7200秒) B --> C{前端需在} C --> D(签名过期前使用) D -->|过期处理| E[重新获取签名] ``` 3. **常见错误码处理**: | 错误码 | 原因 | 解决方案 | |--------|---------------------|-----------------------------| | 40001 | 密钥错误 | 检查`corpsecret`是否正确 | | 40014 | access_token失效 | 刷新access_token | | 40091 | jsapi_ticket失效 | 刷新jsapi_ticket | | 50001 | 未配置可信域名 | 后台配置企业可信域名[^1] | > ⚠️ 必须在企业微信后台配置**可信域名**(管理后台→应用管理→选择应用→设置可信域名) #### 五、调试工具推荐 1. 企业微信官方调试工具: `https://work.weixin.qq.com/api/jsapisign` 2. 签名校验方法: ```javascript // 前端验证签名一致性 wx.checkJsApi({ jsApiList: ['checkJsApi'], success: (res) => { console.log('签名校验结果:', res.checkResult.checkJsApi); } }); ``` > 完整文档参考:[企业微信JS-SDK文档](https://work.weixin.qq.com/api/doc/90000/90136/90506)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值