今天公司要求做一个接微信硬件,代码完成后,测试时(使用的不同的公众号),发现一台手机关注后计入应用界扫描成功后,其他的都无法扫描成功,进过测试,发现了一个坑,就是access_token的覆盖。当一台手机扫描后,如果使用其他手机再次扫描,由于access_token的有效时间还在,那么就会使用之前的access_token,这样扫描不会成功,因此解决这个坑就需要在每个不同公众号id下管理一个access_token,这样就不会出现问题。
之前我们保存了access_token是这样的;
private static string mToken = "";//微信access_token
private static DateTime mGetTokenTime;//本次获取access_token的时间 access_token每110分钟超时一次
这样不同的公众号id其实在7200秒内是相同的access_token,会出现覆盖的问题
因此修改变量代码;
private static Dictionary<string, string> mTokenList = new Dictionary<string, string>();//微信access_token集合 解决同一台服务器变量替换的问题
private static Dictionary<string, DateTime> mTokenTimeList = new Dictionary<string, DateTime>();//本次获取access_token的时间集合 access_token每100分钟超时一次
这样一来的每一个键值都保存不同的access_token。
在获取access_token时就应该通过键值对来获取:
private static string getMToken(string appId)
{
string access_token= (mTokenList.Count > 0 && mTokenList.ContainsKey(appId) ? mTokenList[appId] : "");
return access_token;
}
时间差
private static bool timeOut(string appId)
{
if (mTokenTimeList.Count == 0) {
return true;
}
if (!mTokenTimeList.ContainsKey(appId))
{
return true;
}
TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - mTokenTimeList[appId].Ticks);
return ts.Minutes > 110;
}
获取access_token:
public static void GetAccessToken(string appId, string appSecret)
{
string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
string content = WebApply.GET(url);
if (!content.Contains("errcode"))
{
string wxtoken=content.Replace("\"", "").Split(new char[] { ',' })[0].Split(new char[] { ':' })[1];
if (mTokenList.ContainsKey(appId))
{
mTokenList.Remove(appId);
}
mTokenList.Add(appId, wxtoken);
if (mTokenTimeList.ContainsKey(appId))
{
mTokenTimeList.Remove(appId);
}
mTokenTimeList.Add(appId, DateTime.Now);
}
}
同理在获取jsapi_ticket的时候也需要使用键值对来保存。