Prompt access_when timed task is executed in micro messageToken invalidation (short note)

Keywords: Session SQL

Scenario reproduction: The timer task is working, but when the timer function executes regularly, the error message access_is printed in the logToken fails (or cannot be obtained, etc.), access_in the test tableToken is 0; access_is available when you directly access a link to a timer function yourselfToken.

Reason: When I execute by myself, I open the link in the micro-mail to execute Get access_The token function passes the token value of "Use WeChat"; while the function executes regularly without using WeChat, that is, no token parameter is passed to get access_token's function, so you don't get a valid access_token.

Solution: Timed Task Use Get access_The token function passes a long-term valid token parameter, such as the WeChat token of a business contact (just make sure the WeChat keeps an eye on the WeChat public number).

Correlation function:

// Get access_token, automatic with caching
function get_access_token($token = '', $update = false) {
    empty ( $token ) && $token = get_token ();

    $info = get_token_appinfo ( $token );

    // WeChat Open Platform One-Click Binding
    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 );
    }

    // Automatically determine access_Is token invalid, such as automatically getting new
    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;
}

// Get the current user's 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 );
    }
    //Verify to prevent unauthorized public numbers
    /*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;
}

// Get information about the public number
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;
    }
}
// Anti-timeout file_get_contents transformation function
function wp_file_get_contents($url) {
    return get_data ( $url, 30 );
}
// Get data by GET instead of 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 ); // Skip Certificate Check
        curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); // Do not check certificates
        $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 
                ) 
        ) ); // Timeout in seconds

        $res = file_get_contents ( $url, 0, $context );
    }
    return $res;
}

Posted by oldtimer on Mon, 06 Jul 2020 08:28:12 -0700