一、AccessToken必要性

access_token简单来说是公众号调用接口的唯一凭据,很多接口在调用的时候都必须发送一个access_token的参数来标名身份。

前面消息回复为什么没有使用,就是因为我们根本就没有调用接口,都是被动的接收消息和回复消息。

  1. 微信官方文档地址:http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html
  2. 微信官方给出的建议和要求:
  • 开发者需要进行妥善保存。
  • access_token的存储至少要保留512个字符空间。
  • access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

二、注意事项-AccessToken

前面的url验证和消息回复都没有涉及access_token,但是涉及到菜单以及其他的类似操作都是需要access_token的。

1、access_token的获取

我使用 file_get_contents 通过php进行get请求

得到的是json数据串,json_decode之后就可以拿到access_token和刷新时间。

2、access_token的存储和刷新

  • access_token不能每调用一个接口就请求一次,因此他必须在服务器上进行保存,微信有调用的上限。
  • access_token存储在本地的有效使用时间是7200秒(2小时),过了2小时之后,这个access_token就没用了,需要重新获取
  • 一旦获取了新的access_token上次获取的access_token就失效了,新的access_token需要替代之前的。

一般使用数据库存储比较方便:

  1. 将access_token以及后面需要获取的jsapi_ticket(js-sdk的调用需要的凭据),还有获取的时间(自己生成)存入表中。
  2. 每次从数据库中取access_token,并比较时间差,如果时间差小雨7200秒(适量减少点儿),则重新获取access_token,然后在数据库中进行更新。

三、代码

还是使用函数举例子

这个函数我将jsspi_ticket和access_token写在了一起,是从一个项目中拿出来的,函数是全局的,哪里都能用,因为要保证其他地方能随时获取token

//从数据库中获得access token 和 js ticket

function getToken(){
    //数据库中获取现有的token
    $tokenRes=M('token')->where(array('guid'=>1))->find();

    //时间超过了7200 这个时间是根据获取access_token的时间计算的

    //如果access_token的时间超时了 则js ticket的时间也即将超时

    if(time()-$tokenRes['time']>=7200 || count($tokenRes)==0){

        //超时刷新时间 并再次获取

        refreshToken();

        $tokenRes=M('weixin_token')->where(array('guid'=>1))->find();

        return $tokenRes;

    }else{

        return $tokenRes;

    }

}

//重新生成access_token和js ticket并存储在数据库中

function refreshToken(){
//首先请求accesstoken
    $accessTokenRes=getAccessToken();

    $accessToken=$accessTokenRes['access_token'];
//获取jsapi_ticket
    $jsTicketRes=getJsTicket($accessToken);

    $jsTicket=$jsTicketRes['ticket'];

    if(strlen($accessToken)==0 || strlen($jsTicket)==0){

        return false;

    }else{

        $data=array(

            'access_token'=>$accessToken,

            'js_ticket'=>$jsTicket,

            'time'=>$accessTokenRes['time'],

            'date'=>date('Y-m-d H:i:s',$accessTokenRes['time'])

        );

        //保存到数据库中

        M('weixin_token')->where(array('guid'=>1))->save($data);

        return true;

    }

}
//通用函数 通过api获取access token等操作

function getAccessToken(){
    //构建url必要的是appid和appsecret
    $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.C('APP_ID').'&secret='.C('APP_SECRET');
    //get请求
    $accessKeyRes=file_get_contents($url);//get
    //json解析
    $accessKeyRes=json_decode($accessKeyRes,true);

    //得到accessToken的时间

    $accessKeyRes['time']=time();

    return $accessKeyRes;

}
//获取 js ticket

function getJsTicket($accessToken=''){

    $url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$accessToken.'&type=jsapi';

    $jsTicketRes=file_get_contents($url);//get

    $jsTicketRes=json_decode($jsTicketRes,true);

    return $jsTicketRes;

}

三、数据表

我就建了一个非常简单的数据表:

postbird-weixin

四、注意

记录的时间应当以access_token的获取时间记录,因为jsapi_ticket也是要通过access_token获取的,因此access_token失效的时候,同时刷新jsapi_ticket就可以了。