技术饭
reach max api daily quota limit,微信公众号获取access_token次数受限制
reach max api daily quota limit,微信公众号获取access_token次数受限制,微信公众号获取token分为2种,一种是直接获取access_token,一种是用户授权获取access_token。access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
1、建议公众号开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已超时的情况下,可以触发access_token的刷新流程。
4、公众号和小程序均可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在“微信公众平台-开发-基本配置”页中获得(需要已经成为开发者,且帐号没有异常状态)。调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功。小程序无需配置IP白名单。
4-1、首先不得不提到access_token的分类,一是普通access_token,二是网页授权access_token。其中前者是用于调用微信提供的各种借口,作为开发者的调用凭证,一般有效期为7200S,获取次数受限;另一种是第三方网页若需要使用用户微信账户登录,需要获取该access_token从而来获取用户微信账户信息。这个一定得区分开。
4-2、另外获取用户微信账户信息也有两种情况,一是普通的获取用户信息,它只需要调用微信用户信息接口即可获取,因而使用到的是第一种普通access_token,另一种就是上面提到的网页授权时获取用户信息。一旦二者概念混淆,则会报出invalid access_token错误。
4-3、对于第一种普通access_token,需要注意到的是,它是全局性的,就是一旦获取到了新的access_token,原有的access_token就会失效,而无法调用相关接口。而这种特性,导致的情况是,多个不同进程相互独立获取access_token时,会直接影响到其他进程调用相关微信接口,这种异常通常对应着 access_token失效异常。
为了解决这种情况,必须独立启动一个线程定时去获取access_token,并由该线程向所有其他线程提供该access_token,从而避免access_token获取混乱导致的失效问题。我实现该想法的方式是采用timer定时器,定时刷新获取access_token,并将其存入到指定property文件中,其他线程通过读取该文件中的access_token值,来调用相关接口。
PHP代码:
/**
* 获取access_token,用于后续接口访问
* @return array access_token信息,包含 token 和有效期
*/
public function getAccessToken($type = 'client', $code = null){
$param = array(
'appid' => $this->appId,
'secret' => $this->appSecret
);
switch ($type) {
case 'client':
$param['grant_type'] = 'client_credential';
$url = "{$this->apiURL}/token";
break;
case 'code':
$param['code'] = $code;
$param['grant_type'] = 'authorization_code';
$url = "{$this->oauthApiURL}/oauth2/access_token";
break;
default:
throw new \Exception('不支持的grant_type类型!');
break;
}
//获取缓存token信息,客户端部分用于分享等操作
$client_access_token_info = cache('client_access_token_info');
if($type == 'client' && !empty($client_access_token_info)){
$token = json_decode($client_access_token_info, true);
} else {
$token = self::http($url, $param);
$token = json_decode($token, true);
}
if(is_array($token)){
if(isset($token['errcode'])){
//throw new \Exception($token['errmsg']);
return $token;
} else {
$this->accessToken = $token['access_token'];
//生成缓存
if($type == 'client' && empty($client_access_token_info)){
cache('client_access_token_info', json_encode($token), $token['expires_in']);
}
return $token;
}
} else {
throw new \Exception('获取微信access_token失败!');
}
}
总结:这里只解决了客户端获取access_token进行缓存的方式,如果是授权方式:服务端可以初始给客户端生成一个随机码,客户端保存随机码,每次请求都从头部发送随机码,然后再去做授权用户信息的保存
资料参考:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
https://blog.csdn.net/u013248535/article/details/52613632
文明上网理性发言!