微信中定时任务执行时,提示access_token失效(小记)

本文探讨了定时任务执行时access_token失效的原因,并提供了解决方案。通过传递长期有效的token参数来确保定时任务能够正常获取access_token。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

情景再现:定时任务通了,但定时函数定时执行时,日志中打印出错误信息access_token失效(或获取不到等),测试表中的access_token为0;而自己直接访问定时函数的链接时是可以获取到access_token的。

原因:自己执行时,是在微信中打开的链接,这样执行获取access_token的函数时传递了“使用微信”的token值;而定时函数定时执行时,没有使用微信,即没有token参数传递给获取access_token的函数,这样就获取不到有效的access_token。

解决方法:定时任务使用获取access_token函数时,传递一个长期有效的token参数,如商家联系人的微信token(保证该微信一直关注微信公众号即可)。

相关函数:

// 获取access_token,自动带缓存功能
function get_access_token($token = '', $update = false) {
    empty ( $token ) && $token = get_token ();

    $info = get_token_appinfo ( $token );

    // 微信开放平台一键绑定
    if ($token == 'gh_3c884a361561' || $info ['is_bind']) {
        $access_token = get_authorizer_access_token ( $info ['appid'], $info ['authorizer_refresh_token'], $update );
    } else {
        $access_token = get_access_token_by_apppid ( $info ['appid'], $info ['secret'], $update );
    }

    // 自动判断access_token是否已失效,如失效自动获取新的
    if ($update == false) {
        $url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=' . $access_token;
        $res = wp_file_get_contents ( $url );
        $res = json_decode ( $res, true );
        if ($res ['errcode'] == '40001') {
            $access_token = get_access_token ( $token, true );
        }
    }

    return $access_token;
}

// 获取当前用户的Token
function get_token($token = NULL) {
    $stoken = session ( 'token' );

    $reset = false;
    if ($token !== NULL && $token != '-1') {
        session ( 'token', $token );
        $reset = true;
    } elseif (! empty ( $_REQUEST ['token'] ) && $_REQUEST ['token'] != '-1') {
        session ( 'token', $_REQUEST ['token'] );
        $reset = true;
    } elseif (! empty ( $_REQUEST ['publicid'] )) {
        $publicid = I ( 'publicid' );
        $token = D ( 'Common/Public' )->getInfo ( $publicid, 'token' );
        $token && session ( 'token', $token );
        $reset = true;
    }
    $token = session ( 'token' );

    if (! empty ( $token ) && $token != '-1' && $stoken != $token && $GLOBALS ['is_wap']) {
        session ( 'mid', null );
    }
    //加校验,防止使用无权限的公众号
    /*if(!$GLOBALS['is_wap'] && $reset){
        if(empty($GLOBALS['myinfo'])) $token = -1;
        else{
            $sql = 'SELECT public_id FROM `'.C('DB_PREFIX').'public_link` as l LEFT JOIN '.C('DB_PREFIX').'public as p on l.mp_id=p.id WHERE l.uid='.$GLOBALS['mid'];
            $list = M()->query($sql);
            $flat = false;
            foreach ($list as $value) {
                if($value['public_id']==$token){
                    $flat = true;
                }
            }

            if(!$flat) $token = -1;
        }
    }*/

    if (empty ( $token ) ) {
        $token = -1;
    }

    return $token;
}

// 获取公众号的信息
function get_token_appinfo($token = '', $field = '') {
    empty ( $token ) && $token = get_token ();
    if ($token != 'gh_3c884a361561') {
        $info = D ( 'Common/Public' )->getInfoByToken ( $token, $field );
    }
    return $info;
}

function get_authorizer_access_token($appid, $refresh_token, $update) {
    if (empty ( $appid )) {
        return 0;
    }

    $key = 'authorizer_access_token_' . $appid;
    $res = S ( $key );
    if ($res !== false && ! $update)
        return $res;

    $dao = D ( 'Addons://PublicBind/PublicBind' );
    if (empty ( $refresh_token )) {
        $auth_code = $dao->_get_pre_auth_code ();
        $info = $dao->getAuthInfo ( $auth_code );
        $authorizer_access_token = $info ['authorization_info'] ['authorizer_access_token'];
    } else {
        $info = $dao->refreshToken ( $appid, $refresh_token );
        $authorizer_access_token = $info ['authorizer_access_token'];
    }

    if (! empty ( $authorizer_access_token )) {
        S ( $key, $authorizer_access_token, $info ['expires_in'] - 200 );
        return $authorizer_access_token;
    } else {
        addWeixinLog ( $info, 'get_authorizer_access_token_fail_' . $appid );
        return 0;
    }
}
function get_access_token_by_apppid($appid, $secret, $update = false) {
    if (empty ( $appid ) || empty ( $secret )) {
        return 0;
    }

    $key = 'access_token_apppid_' . $appid . '_' . $secret;
    $res = S ( $key );
    if ($res !== false && ! $update)
        return $res;

    $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&secret=' . $secret . '&appid=' . $appid;
    $tempArr = json_decode ( get_data ( $url ), true );
    if (@array_key_exists ( 'access_token', $tempArr )) {
        S ( $key, $tempArr ['access_token'], $tempArr ['expires_in'] );
        return $tempArr ['access_token'];
    } else {
        return 0;
    }
}
// 防超时的file_get_contents改造函数
function wp_file_get_contents($url) {
    return get_data ( $url, 30 );
}
// 以GET方式获取数据,替代file_get_contents
function get_data($url, $timeout = 5) {
    $msg = $flat = '';
    if (strpos ( $url, 'http://' ) !== false || strpos ( $url, 'https://' ) !== false) {

        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_URL, $url );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );

        curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); // 跳过证书检查
        curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); // 不检查证书
        $res = curl_exec ( $ch );

        $flat = curl_errno ( $ch );
        if ($flat) {
            $msg = curl_error ( $ch );
        }
        curl_close ( $ch );
    } else {
        $context = stream_context_create ( array (
                'http' => array (
                        'timeout' => 30 
                ) 
        ) ); // 超时时间,单位为秒

        $res = file_get_contents ( $url, 0, $context );
    }
    return $res;
}
### 回答1: 当微信开发工具提示 "access_token is invalid or not latest"(access_token无效或者不是最新的),这通常表示当前使用的access_token已过期或者已被撤销,需要重新获取一个最新的access_token。 在微信开发中,access_token是用来进行微信接口调用的重要凭证。由于access_token的有效期较短(通常为2小),因此在开发过程中,需要定期刷新access_token,以确保能够正常调用微信接口。 获取最新的access_token可以通过向微信服务器发送请求来获取。具体的获取方法是向微信服务器发送GET请求,请求地址为https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,其中APPID为微信公众号的AppID,APPSECRET为微信公众号的AppSecret。 获取到最新的access_token后,需要将其保存起来,并在每次调用微信接口进行使用。同,定刷新access_token是一个良好的开发习惯,可以避免由于access_token过期而导致的接口调用失败。 所以,当微信开发工具提示 "access_token is invalid or not latest",我们需要检查当前的access_token是否已过期,如果过期则通过上述步骤获取一个最新的access_token,并更新到开发工具中,以确保能够正常进行微信接口的调用。 ### 回答2: 微信开发工具给出"access_token is invalid or not latest"这个提示,意味着使用的access_token无效或者不是最新的。 access_token是用于调用微信开放平台接口的重要凭证,每个应用都需要获取有效的access_token才能进行接口的访问和操作。验证access_token是否有效和最新主要考虑以下两个因素: 1. 有效性:access_token的有效期为2小,超过2小后需要重新获取新的access_token。所以如果提示是无效的,可能是因为已经过期了,需要重新获取新的access_token。 2. 最新性:在获取access_token之后,如果有进一步的操作(例如获取或更新用户信息、发布消息等),可能会导致access_token被刷新。这样旧的access_token失效,需要使用最新的access_token才能继续操作。提示不是最新的access_token可能是因为在之前的操作中,access_token已经被刷新过了。 解决这个问题的方法是: 1. 检查access_token是否已经过期了,如果过期了,则需要重新获取新的access_token。 2. 如果access_token是最新的,那么可能是因为在之前的操作中,access_token已经被刷新过了。解决方法是更新代码中的access_token,使用最新的access_token进行后续操作。 总之,当微信开发工具提示"access_token is invalid or not latest",开发者需要验证并更新access_token,确保它的有效性和最新性,以确保后续接口调用的成功。 ### 回答3: 微信开发工具提示"access_token is invalid or not latest"是由于我们在使用微信开发接口,所使用的access_token无效或者不是最新的。 在使用微信开发接口,我们需要先获取一个access_token,它是调用微信开发接口的凭证。access_token是有效性的,一般在2小后会过期,我们需要定期更新。如果我们在使用使用了一个无效的或者过期的access_token微信开发工具就会提示"access_token is invalid or not latest"。 出现这个问题的原因可能有以下几点: 1. access_token过期:在获取access_token后,由于间过长或者其他原因,我们没有及更新和使用新的access_token。 2. 缓存和保存问题:我们没有正确地缓存和保存access_token,导致在使用被认为是无效或者过期的。 3. 接口调用限制:我们在一定间内调用接口的次数超过了微信的限制,导致access_token被封禁或者自动失效。 解决这个问题的方法是: 1. 定期更新access_token:我们可以设置一个定时任务,在access_token接近过期自动更新。也可以在每次使用之前都重新获取一次access_token。 2. 正确缓存和保存access_token:在获取access_token后,将其正确地缓存和保存起来,在使用获取和更新。 3. 规避接口调用限制:合理控制接口的调用频率,避免在一定间内调用过多次导致访问受限。 总之,微信开发工具提示"access_token is invalid or not latest"是因为我们使用了无效或者过期的access_token,我们需要定期更新access_token,并正确地缓存和保存它,同合理控制接口的调用频率,以解决这个问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值