微信公众平台开发动态获取与更新access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

公众平台的API调用所需的access_token的使用及生成方式说明:

1、建议公众号开发者使用中控服务器统一获取和刷新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的刷新流程。

公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。

请求地址:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求方法:
GET

参数说明:

根据官方文档,帅华君写了一个更新access_token到数据库中的函数,仅供参考,这里用到了一些模块,比如httphttpsmysql

const updateAccessToken = (cb) => {
	const AppID = '这里填写你的AppID';
	const AppSecret = '这里填写AppSecret';

	const hostname = 'api.weixin.qq.com';
	const path = '/cgi-bin/token?grant_type=client_credential&appid=' + AppID + '&secret=' + AppSecret;
	const url = 'https://' + hostname + path;

	var data = '', access_token, expires_in, expires;

	https.get(url, (res) => {
		res.on('data', (d) => {
			data += d;
		});
		res.on('end', () => {
			data = JSON.parse(data);
			access_token = data['access_token'];
			expires_in = Number(data['expires_in']);

			var timestamp = (new Date())
				.getTime();
			expires = timestamp + expires_in * 1000;

			const sql = 'UPDATE `wechat_access_token` SET `access_token` = "' + access_token + '", `expires` = "' + expires + '"';
			mysqlQuery(sql, (e, r) => {
				if (e) {
					cb({
						flag: false,
						info: e
					});
				} else {
					// 已更新
					cb({
						flag: true,
						access_token: access_token,
						expires: expires
					});
				}
			});
		});
	});
}

每调用一次updateAccessToken函数都会想微信服务器请求一次access_token,而官方文档指出每日调用次数有限制,因此断不可每次需要access_token时通过该方法获取,因此才需要将获取到的access_token存入数据库中,并把过期时间也存入数据库。

微信服务器返回的access_token数据格式如下:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

参数说明:

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

返回码说明:

所以,帅华君又写了下面这一函数用来获取access_token,该函数会先去数据库中查询当前的access_token有无过期,如无过期,则直接返回该access_token,如若过期,则才会调用上方更新access_token的函数。

const getAccessionToken = (cb) => {
	const sql = 'SELECT * FROM `wechat_access_token`';
	mysqlQuery(sql, (e, r) => {
		const expires = Number(r[0]['expires'])
		const access_token = r[0]['access_token']
		const timestamp = (new Date()).getTime();
		if (timestamp < expires) {
			// console.log('未过期');
			cb({
				flag: true,
				access_token: access_token,
				expires: expires
			});
		} else {
			// console.log('过期,需要更新access_token!');
			updateAccessToken(cb);
		}
	});
}

当时帅华君在过期时间这里犯了一次傻,由于微信返回的过期时间是以秒为单位,即7200秒,将获取到access_token时的时间加上过期时长即是过期时间。可是帅华君错误的把**new Date().getTime()**得到的时间戳直接加上了7200,后来找了好一会儿才发现问题出在哪,需要把秒乘以1000换算成毫秒再加上获取到access_token时的时间戳就可以了。所以啊,凡事既要把握大局亦要着眼于细节,但终归要回归大局。

下一篇《微信公众平台开发获取微信服务器IP地址》

上一篇《搞定微信公众平台开发者基本配置》

永久链接 http://www.shuaihua.cc/article/wechat-development-server-side-update-access_tocken-dynamic

快速跳转 心头好文 - language - 《微信公众平台开发动态获取与更新access_token》

发布日期 2017年9月5日 星期二

版权声明 自由转载-非商用-非衍生-保持署名(创意共享3.0许可证