如何使用谷歌API客户端刷新令牌?

我一直在玩Google Analytics API(V3),并遇到了som错误。首先,一切都设置正确,并使用我的测试帐户。但是,当我想从另一个配置文件ID(相同的Google Accont / GA帐户)获取数据时,我会收到403错误。奇怪的是,来自某些GA帐户的数据将返回数据,而其他帐户将生成此错误。

我已经吊销了令牌并再次进行身份验证,现在看来我可以从所有帐户中获取数据。问题解决了?不。由于访问密钥将过期,我将再次遇到相同的问题。

如果我理解正确,可以使用 resfreshToken 来获得新的 authenticationTooken。

问题是,当我运行时:

$client->refreshToken(refresh_token_key) 

返回以下错误:

Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'

我已经检查了 refreshToken 方法背后的代码,并将请求跟踪回“apiOAuth2.php”文件。正确发送所有参数。grant_type硬编码为方法中的“refresh_token”,因此我很难理解出了什么问题。参数数组如下所示:

Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )

操作步骤如下。

$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');

$client->setAccessToken($config['token']); // The access JSON object.

$client->refreshToken($config['refreshToken']); // Will return error here

这是一个错误,还是我完全误解了什么?


答案 1

所以我终于想出了如何做到这一点。基本思想是,您拥有首次请求身份验证时获得的令牌。第一个令牌具有刷新令牌。第一个原始令牌将在一小时后过期。一小时后,必须使用第一个令牌中的刷新令牌才能获取新的可用令牌。用于检索新令牌。我称之为“临时令牌”。您还需要存储此临时令牌,因为一小时后它也会过期,请注意它没有与之关联的刷新令牌。为了获取新的临时令牌,您需要使用之前使用的方法并使用第一个令牌的刷新令牌。我在下面附加了代码,这很丑陋,但是我是新手...$client->refreshToken($refreshToken)

//pull token from database
$tokenquery="SELECT * FROM token WHERE type='original'";
$tokenresult = mysqli_query($cxn,$tokenquery);
if($tokenresult!=0)
{
    $tokenrow=mysqli_fetch_array($tokenresult);
    extract($tokenrow);
}
$time_created = json_decode($token)->created;
$t=time();
$timediff=$t-$time_created;
echo $timediff."<br>";
$refreshToken= json_decode($token)->refresh_token;


//start google client note:
$client = new Google_Client();
$client->setApplicationName('');
$client->setScopes(array());
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setAccessType('offline');
$client->setDeveloperKey('');

//resets token if expired
if(($timediff>3600)&&($token!=''))
{
    echo $refreshToken."</br>";
    $refreshquery="SELECT * FROM token WHERE type='refresh'";
    $refreshresult = mysqli_query($cxn,$refreshquery);
    //if a refresh token is in there...
    if($refreshresult!=0)
    {
        $refreshrow=mysqli_fetch_array($refreshresult);
        extract($refreshrow);
        $refresh_created = json_decode($token)->created;
        $refreshtimediff=$t-$refresh_created;
        echo "Refresh Time Diff: ".$refreshtimediff."</br>";
        //if refresh token is expired
        if($refreshtimediff>3600)
        {
            $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="UPDATE token SET token='$newtoken' WHERE type='refresh'";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed again";
        }
        //if the refresh token hasn't expired, set token as the refresh token
        else
        {
        $client->setAccessToken($token);
           echo "use refreshed token but not time yet";
        }
    }
    //if a refresh token isn't in there...
    else
    {
        $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="INSERT INTO token (type,token) VALUES ('refresh','$newtoken')";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed for first time";
    }      
}

//if token is still good.
if(($timediff<3600)&&($token!=''))
{
    $client->setAccessToken($token);
}

$service = new Google_DfareportingService($client);

答案 2

问题出在刷新令牌中:

[refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

当一个字符串带有a get时,它被转义为a,因此你需要删除它。'/'json encoded'\'

在这种情况下,刷新令牌应为:

1/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

我假设你已经做的是,你已经打印了谷歌发回的json字符串,并将令牌复制并粘贴到你的代码中,因为如果你这样做,那么它会正确地为你删除!json_decode'\'


推荐