Google API istemcisi ile jeton nasıl yenilenir?


92

Google Analytics API (V3) ile uğraşıyorum ve bazı hatalarla karşılaştım. İlk olarak, her şey doğru bir şekilde kuruldu ve test hesabımla çalıştı. Ancak başka bir profil kimliğinden (Aynı Google Hesabı / GA Hesabı) veri almak istediğimde 403 Hatası alıyorum. Garip olan şey, bazı GA hesaplarındaki verilerin veri döndürürken diğerlerinin bu hatayı oluşturmasıdır.

Belirteci iptal ettim ve bir kez daha kimlik doğrulamasını yaptım ve şimdi tüm hesaplarımdan veri alabiliyorum gibi görünüyor. Sorun çözüldü? Değil. Erişim anahtarının süresi dolacağı için aynı sorunla tekrar karşılaşacağım.

Her şeyi doğru anladıysam, yeni bir authenticationTooken almak için resfreshToken kullanılabilir.

Sorun şu ki, koştuğumda:

$client->refreshToken(refresh_token_key) 

aşağıdaki hata döndürülür:

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

RefreshToken yönteminin arkasındaki kodu kontrol ettim ve isteği "apiOAuth2.php" dosyasına geri izledim. Tüm parametreler doğru şekilde gönderilir. Grant_type, yöntem içinde 'refresh_token' olarak kodlanmıştır, bu nedenle neyin yanlış olduğunu anlamak benim için zor. Parametre dizisi şuna benzer:

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

Prosedür aşağıdaki gibidir.

$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

Bu bir hata mı yoksa bir şeyi tamamen yanlış mı anladım?


Hata mı yoksa başka bir şey mi bilmiyorum ama şu anda ham CURL http isteği kullanarak erişim belirtecini yeniliyor ve iyi çalışıyor.
gremo

Seorch ... bunu çözdün mü? Burada aynı sorun.
Brian Vanderbusch

@gremo, burada kullandığınız ham CURL http talebini paylaşabilir misiniz? Gerçekten yardımcı olur. Teşekkürler!
Silver Ringvee

Yanıtlar:


76

Sonunda bunu nasıl yapacağımı buldum. Temel fikir, kimlik doğrulaması için ilk istediğinizde aldığınız jetona sahip olmanızdır. Bu ilk jetonun bir yenileme jetonu vardır. İlk orijinal jetonun süresi bir saat sonra dolar. Bir saat sonra, yeni bir kullanılabilir jeton almak için ilk jetondan yenileme jetonunu kullanmanız gerekir. $client->refreshToken($refreshToken)Yeni bir belirteç almak için kullanırsınız . Ben buna "geçici jeton" diyeceğim. Bu geçici jetonu da saklamanız gerekir, çünkü bir saat sonra da sona erer ve onunla ilişkili bir yenileme jetonuna sahip olmadığını unutmayın. Yeni bir geçici jeton almak için daha önce kullandığınız yöntemi kullanmanız ve ilk jetonun yenileme jetonunu kullanmanız gerekir. Aşağıya kod ekledim, bu çirkin, ama bu konuda yeniyim ...

//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);

52
3600 saniyeyi kontrol etmek yerine, $ client-> isAccessTokenExpired ()
Gaurav Gupta

2
Küçük güncelleme. En son sürümde, bir yenileme belirteci talep ettiğinizde, döndürülen yeni erişim belirteci artık yeni bir yenileme belirteciyle birlikte gelir. Dolayısıyla, temel olarak, önceki json belirtecini değiştirmek için güncellenmiş json belirtecini kullanabilirsiniz ve artık ilk erişim belirtecini saklamanıza gerek kalmaz. .
skidadon

1
$client->isAccessTokenExpired()Belirtecin süresinin dolduğunu düşünüp düşünmediğini görmek için yalnızca yerel olarak tutulan süreleri kontrol edeceğini unutmayın . Jetonun süresi hala dolmuş olabilir ve yerel uygulama yalnızca onu kullanmaya çalıştığında gerçekten bilecektir. Bu durumda API istemci istisna döndürür ve olacak değil otomatik belirteci yenileyin.
Jason

@Jason şimdi doğru değil sanırım. "İsAccessTokenExpired" yönteminde aşağıdaki return ifadesini görüyorum: return ($ created + ($ this-> token ['expires_in'] - 30)) <time ();
sudip

44

Sorun, yenileme simgesinde:

[refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Bir dizi '/'alırsa json encoded, bir ile kaçar '\', dolayısıyla onu kaldırmanız gerekir.

Durumunuzdaki yenileme belirteci şöyle olmalıdır:

1/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

Yaptığınızı varsaydığım şey, Google'ın geri gönderdiği ve jetonu kopyalayıp kodunuza yapıştırdığı json dizesini yazdırdığınızdır, çünkü eğer bunu yaparsanız sizin json_decodeiçin doğru bir şekilde kaldıracaktır '\'!


1
harika söz, günümü yaptı! saat tasarrufu!
Mircea Sandu

Günümü kurtardın!
Truong Dang

Keşke bunu 100 kez yükseltebilseydim. Simgeyi çalıştırmak için kesinlikle her şeyi denedikten sonra birkaç saat "kötü hibe" mesajına baktıktan sonra klavyemle duvara bir delik açmak üzereydim. Kahrolası google adam, neden eğik çizgi kullanıyorsun, sadece neden?
Askerman

18

İşte jetonu ayarlamak için snippet, bundan önce erişim türünün çevrimdışı olarak ayarlanmasını sağlayın

if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['access_token'] = $client->getAccessToken();
}

Jetonu yenilemek için

$google_token= json_decode($_SESSION['access_token']);
$client->refreshToken($google_token->refresh_token);

bu, jetonunuzu yeniler, yapabilmeniz için oturumda güncellemeniz gerekir

 $_SESSION['access_token']= $client->getAccessToken()

1
günümü bununla yaptın :) çok teşekkür ederim, düşündüğümden çok daha basit, çünkü hiçbir yere varmak için çok zaman harcıyordum: D
TB Ygg

16

Erişim türü olarak ayarlanmalıdır offline. stateAPI'nin kullanımı için değil, kendi kullanımınız için belirlediğiniz bir değişkendir.

İstemci kitaplığının en son sürümüne sahip olduğunuzdan emin olun ve şunu ekleyin:

$client->setAccessType('offline');

Parametrelerin açıklaması için URL'yi Oluşturma bölümüne bakın .


Teşekkürler jk. En son sürümü indirdim ve hesabım için uygulamaya erişimi iptal ettim. Sonra bir kez daha erişim izni verdim ve accessToken ve renewToken'ı sakladım. Mesele şu ki, setAccessType atlanmış olsa bile bana her zaman bir renewToken verildi. Her neyse, $ client-> renewToken'ı (yenileme-belirteci-anahtarı) çalıştırdığımda, yine de "geçersiz_grant" hatası alıyorum. Auth-url'yi kontrol ettim ve varsayılan olarak "force" olarak ayarlandı. Bunu "otomatik" olarak değiştirirsem ve kimlik doğrulama yöntemini çalıştırırsam, zaten erişim izni verdiğim için yönlendirilmem. Ancak yanıt, yenilenmemiş bir erişim belirteci. Herhangi bir fikir?
seorch.me

@ seorch.me Kulağa çılgınca geliyor ama yenileme belirtecini kullanmak için yeni bir $client( $client = new apiClient();) ayarlamanız gerekebilir mi?
jk.

1
@ seorch.me yetkilendirme sırasında yeni bir yenileme belirteci almanın $client->setApprovalPrompt('force')yanı sıra ayarlamanız gerekir $client->setAccessType('offline'). Google, kullanıcıyı erişim kapsamını onaylamaya zorlamadan eski yenileme jetonunu kullanmaya devam edeceğinizi varsayar.
Jason

14

@ Uri-weg tarafından gönderilen cevap benim için işe yaradı ama açıklamalarını çok net bulamadığım için biraz yeniden ifade edeyim.

İlk erişim izni sırasında, geri aramada, bir kimlik doğrulama kodu aldığınız noktaya geldiğinizde , erişim kodunu ve yenileme belirtecini de kaydetmelisiniz .

Bunun nedeni, google api'nin size yalnızca erişim izni istendiğinde yenileme belirteci içeren bir erişim belirteci göndermesidir. Sonraki erişim belirteçleri herhangi bir yenileme belirteci olmadan gönderilecektir ( approval_prompt=forceseçeneği kullanmadığınız sürece ).

İlk kez aldığınız yenileme belirteci, kullanıcı erişim iznini iptal edene kadar geçerli kalır.

Basit php'de, geri arama dizisinin bir örneği şöyle olacaktır:

// init client
// ...

$authCode = $_GET['code'];
$accessToken = $client->authenticate($authCode);
// $accessToken needs to be serialized as json
$this->saveAccessToken(json_encode($accessToken));
$this->saveRefreshToken($accessToken['refresh_token']);

Ve daha sonra, basit php'de bağlantı sırası şöyle olacaktır:

// init client
// ...

$accessToken = $this->loadAccessToken();
// setAccessToken() expects json
$client->setAccessToken($accessToken);

if ($client->isAccessTokenExpired()) {
    // reuse the same refresh token
    $client->refreshToken($this->loadRefreshToken());
    // save the new access token (which comes without any refresh token)
    $this->saveAccessToken($client->getAccessToken());
}

mükemmel, çok çalıştı. Söyleyeceğim tek şey, json nesnesini bir dizge olarak yalnızca belirteci değil, iletmeniz gerektiğini açıklamalısınız.
Oliver Bayes-Shelton

@ OliverBayes-Shelton Merhaba. Teşekkürler. // setAccessToken() expects jsonYeterli olduğunu düşündüm . Yoksa kodun başka bir parçası için mi?
Daishi

Bu benim için harika çalışıyor, ancak bu kodun, 50 simge yenileme sınırının aşılması nedeniyle bir belirtecin süresinin dolduğu durumları ele alıp almadığını biliyor musunuz? 'Token Son Kullanma Tarihi' ile ilgili ayrıntılar burada bulunabilir: developers.google.com/identity/protocols/OAuth2#expiration
Bjorn

Görünüşe göre en son 2.0 sürümü artık erişim belirteci dizisindeki yenileme belirtecini döndürüyor. Bu, erişim belirtecini kaydetmenin, yenileme belirteci dahil edildiğinden yenileme belirtecini de kaydettiği anlamına gelir. Yenileme belirtecinin süresinin dolmasına yanıt olarak, bunun açıkça test edilmesi ve kullanılması gerektiğini tahmin ediyorum - 50 sınırının "istemci başına kullanıcı başına" olduğunu, yani istemci başına 50 olduğunu unutmayın; bu nedenle, özellikle belirteçleri birleştirmek için dahil edilen kapsamları kullanırsınız.
Brian C

8

İşte projemde kullandığım kod ve iyi çalışıyor:

public function getClient(){
    $client = new Google_Client();
    $client->setApplicationName(APPNAME);       // app name
    $client->setClientId(CLIENTID);             // client id
    $client->setClientSecret(CLIENTSECRET);     // client secret 
    $client->setRedirectUri(REDIRECT_URI);      // redirect uri
    $client->setApprovalPrompt('auto');

    $client->setAccessType('offline');         // generates refresh token

    $token = $_COOKIE['ACCESSTOKEN'];          // fetch from cookie

    // if token is present in cookie
    if($token){
        // use the same token
        $client->setAccessToken($token);
    }

    // this line gets the new token if the cookie token was not present
    // otherwise, the same cookie token
    $token = $client->getAccessToken();

    if($client->isAccessTokenExpired()){  // if token expired
        $refreshToken = json_decode($token)->refresh_token;

        // refresh the token
        $client->refreshToken($refreshToken);
    }

    return $client;
}

6

Aynı sorunu yaşadım; Dün işe yarayan senaryom, garip bir nedenden dolayı bugün işe yaramadı. Değişiklik yok.

Görünüşe göre bunun nedeni sistem saatimin 2,5 (!!) saniye kapalı olmasıydı, NTP ile senkronizasyon bunu düzeltti.

Ayrıca bkz .: https://code.google.com/p/google-api-php-client/wiki/OAuth2#Solving_invalid_grant_errors


Bu cevap bana çok yardımcı oldu dostum. Muhtemelen bana çok zaman kazandırdın. Çok! Teşekkürler! Sadece idam sudo apt-get install ntpNTP yüklemek için benim Debian makinede. Saati senkronize etti ve sorun çözüldü.
Szymon Sadło

4

Bilginize: 3.0 Google Analytics API, süresi dolduğunda bir yenileme jetonunuz varsa erişim jetonunu otomatik olarak yenileyecektir, böylece komut dosyanızın hiçbir zaman ihtiyacı yoktur refreshToken.

(İçindeki Signişleve bakın auth/apiOAuth2.php)


"Otomatik olarak yenileme" sadece getAccessToken () istemem gerektiği ve yenilenmiş bir tane geri alacağım anlamına mı geliyor? Ama önce yenileme belirtecini DB'den ayarlamalıyım, değil mi? Aksi takdirde, yenileme bir yenileme belirteci olmadan çalışır ve bunun işe yarayacağını düşünmüyorum
ninsky

4

Bazen Refresh Token i kullanılarak oluşturulmaz $client->setAccessType ("offline");.

Bunu dene:

$client->setAccessType ("offline");
$client->setApprovalPrompt ("force"); 

Daha spesifik olmak gerekirse, Yenileme belirteci ilk yetkilendirmenize dahil edilmiş gibi görünüyor . Kaydedip daha sonra kullanırsanız, (başkalarına göre doğrulanmamış) yenileme belirtecinin iade edilmeye devam edeceğine inanıyorum. Doco artık bir yenileme belirtecine sahiplerse erişim belirtecini otomatik olarak yenileyeceklerini söylüyor, bu da yalnızca yenileme belirtecini güvenli bir şekilde yönetme meselesi anlamına geliyor. setApprovalPrompt ('force'), bir yenileme belirtecinin daha sonra verilmesini zorlar; onsuz başka bir tane alamazsın.
Brian C

2

Örneği akıllı kodlarla Google API'nin mevcut sürümüyle kullandım, ancak bu işe yaramadı. API'sinin çok eski olduğunu düşünüyorum.

Bu yüzden, API örneklerinden birine dayanarak kendi sürümümü yazdım ... Erişim belirteci, istek belirteci, simge türü, kimlik belirteci, sona erme süresi ve oluşturma zamanını dizeler olarak çıkarıyor

İstemci kimlik bilgileriniz ve geliştirici anahtarınız doğruysa, bu kod kullanıma hazır olmalıdır.

<?php
// Call set_include_path() as needed to point to your client library.
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();

$client = new Google_Client();
$client->setApplicationName("Get Token");
// Visit https://code.google.com/apis/console?api=plus to generate your
// oauth2_client_id, oauth2_client_secret, and to register your oauth2_redirect_uri.
$oauth2 = new Google_Oauth2Service($client);

if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
    return;
}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

if (isset($_REQUEST['logout'])) {
    unset($_SESSION['token']);
    $client->revokeToken();
}
?>
<!doctype html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
        <header><h1>Get Token</h1></header>
        <?php
        if ($client->getAccessToken()) {
            $_SESSION['token'] = $client->getAccessToken();
            $token = json_decode($_SESSION['token']);
            echo "Access Token = " . $token->access_token . '<br/>';
            echo "Refresh Token = " . $token->refresh_token . '<br/>';
            echo "Token type = " . $token->token_type . '<br/>';
            echo "Expires in = " . $token->expires_in . '<br/>';
            echo "ID Token = " . $token->id_token . '<br/>';
            echo "Created = " . $token->created . '<br/>';
            echo "<a class='logout' href='?logout'>Logout</a>";
        } else {
            $authUrl = $client->createAuthUrl();
            print "<a class='login' href='$authUrl'>Connect Me!</a>";
        }
        ?>
    </body>
</html>

1
, Neden bu satırı bana açıklayabilir edin: $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];. Neden aynı sayfaya yönlendiriyorsunuz? bu gerekli mi?
Tropicalista

@Tropicalista: Sayfayı tek başına yeniden yüklemek gerekli değildir, ancak kimlik doğrulama akışlarının tipik olarak uygulanma şekli budur.
John Slegers

ancak erişim belirtecinin süresi dolmuşsa yeni bir erişim belirteci almak için yenileme belirtecini kullanmıyorsunuz.
apadana

2

İlk yetkilendirme isteği sırasında erişim jetonunu dosyaya veya veritabanına json dizesi olarak kaydetmeniz ve erişim türünü çevrimdışı olarak ayarlamanız gerekir. $client->setAccessType("offline")

Ardından, sonraki API istekleri sırasında, dosyanızdan veya veritabanınızdan erişim jetonunu alın ve istemciye iletin:

$accessToken = json_decode($row['token'], true);
$client->setAccessToken($accessToken);

Şimdi jetonun süresinin dolup dolmadığını kontrol etmeniz gerekiyor:

if ($client->isAccessTokenExpired()) {
    // access token has expired, use the refresh token to obtain a new one
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    // save the new token to file or db
    // ...json_encode($client->getAccessToken())

fetchAccessTokenWithRefreshToken()Fonksiyon sizin için işi yapmak ve geri dosya veya veritabanına kaydetmek, yeni bir erişim belirteci sağlayacaktır.


1

Google / google-api-php-client v2.0.0-RC7 ile aynı problemim var ve 1 saat aradıktan sonra bu problemi json_encode kullanarak şu şekilde çözdüm :

    if ($client->isAccessTokenExpired()) {
        $newToken = json_decode(json_encode($client->getAccessToken()));
        $client->refreshToken($newToken->refresh_token);
        file_put_contents(storage_path('app/client_id.txt'), json_encode($client->getAccessToken()));
    }

1

Bu çok iyi çalışıyor, belki herhangi birine yardımcı olabilir:

index.php

session_start();

require_once __DIR__.'/client.php';

if(!isset($obj->error) && isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in)) {
?>
<!DOCTYPE html>
<html>
<head>
<title>Google API Token Test</title>
<meta charset='utf-8' />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
search('Music Mix 2010');
function search(q) {
    $.ajax({
        type: 'GET',
        url: 'action.php?q='+q,
        success: function(data) {
            if(data == 'refresh') location.reload();
            else $('#response').html(JSON.stringify(JSON.parse(data)));
        }
    });
}
</script>
</head>
<body>
<div id="response"></div>
</body>
</html>
<?php
}
else header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/oauth2callback.php', FILTER_SANITIZE_URL));
?>

oauth2callback.php

require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfigFile('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setRedirectUri('https://'.filter_var($_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'], FILTER_SANITIZE_URL));
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

if(isset($_GET['code']) && $_GET['code']) {
    $client->authenticate(filter_var($_GET['code'], FILTER_SANITIZE_STRING));
    $_SESSION['access_token'] = $client->getAccessToken();
    $_SESSION['refresh_token'] = $_SESSION['access_token']['refresh_token'];
    setcookie('refresh_token', $_SESSION['refresh_token'], time()+60*60*24*180, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);
    header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']), FILTER_SANITIZE_URL));
    exit();
}
else header('Location: '.filter_var($client->createAuthUrl(), FILTER_SANITIZE_URL));
exit();

?>

client.php

// https://developers.google.com/api-client-library/php/start/installation
require_once __DIR__.'/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

// Delete Cookie Token
#setcookie('refresh_token', @$_SESSION['refresh_token'], time()-1, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);

// Delete Session Token
#unset($_SESSION['refresh_token']);

if(isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
    $client->refreshToken($_SESSION['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}
elseif(isset($_COOKIE['refresh_token']) && $_COOKIE['refresh_token']) {
    $client->refreshToken($_COOKIE['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}

$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.urlencode(@$_SESSION['access_token']['access_token']);
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Google API Token Test');
$json = curl_exec($curl_handle);
curl_close($curl_handle);

$obj = json_decode($json);

?>

action.php

session_start();

require_once __DIR__.'/client.php';

if(isset($obj->error)) {
    echo 'refresh';
    exit();
}
elseif(isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in) && isset($_GET['q']) && !empty($_GET['q'])) {
    $client->setAccessToken($_SESSION['access_token']);
    $service = new Google_Service_YouTube($client);
    $response = $service->search->listSearch('snippet', array('q' => filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS), 'maxResults' => '1', 'type' => 'video'));
    echo json_encode($response['modelData']);
    exit();
}
?>

1

Google, bu sorunun ilk gönderilmesinden bu yana bazı değişiklikler yaptı.

İşte şu anda çalışan örneğim.

    public function update_token($token){

    try {

        $client = new Google_Client();
        $client->setAccessType("offline"); 
        $client->setAuthConfig(APPPATH . 'vendor' . DIRECTORY_SEPARATOR . 'google' . DIRECTORY_SEPARATOR . 'client_secrets.json');  
        $client->setIncludeGrantedScopes(true); 
        $client->addScope(Google_Service_Calendar::CALENDAR); 
        $client->setAccessToken($token);

        if ($client->isAccessTokenExpired()) {
            $refresh_token = $client->getRefreshToken();
            if(!empty($refresh_token)){
                $client->fetchAccessTokenWithRefreshToken($refresh_token);      
                $token = $client->getAccessToken();
                $token['refresh_token'] = json_decode($refresh_token);
                $token = json_encode($token);
            }
        }

        return $token;

    } catch (Exception $e) { 
        $error = json_decode($e->getMessage());
        if(isset($error->error->message)){
            log_message('error', $error->error->message);
        }
    }


}

1

Google-api-php-client v2.2.2 kullanıyorum fetchAccessTokenWithRefreshToken();if function call with params, o güncellenmiş bir erişim token döndürüyor ve yenilenen token kaybolmuyor.

if ($client->getAccessToken() && $client->isAccessTokenExpired()) {
    $new_token=$client->fetchAccessTokenWithRefreshToken();
    $token_data = $client->verifyIdToken();
}    

0

yenileme jetonunuzu almak için aşağıdaki kod parçacığını kullanın

    <?php

    require_once 'src/apiClient.php';
    require_once 'src/contrib/apiTasksService.php';

    $client = new apiClient();
    $client->setAccessType('offline');
    $tasksService = new apiTasksService($client);

    $auth = $client->authenticate();
    $token = $client->getAccessToken();
    // the refresh token
    $refresh_token = $token['refresh_token'];
    ?>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.