1

我想在訪問令牌過期後使用刷新令牌交換訪問令牌。但是,我這樣做時一直面臨像「invalid_grant」這樣的問題。谷歌OAuth2.0 PHP客戶端交換訪問令牌與刷新令牌

我想在嘗試爲new access_token交換refresh_token時出現了一些問題。我的代碼如下所示:

<?php 
require_once 'google-api-php-client/src/Google_Client.php'; 
require_once 'google-api-php-client/src/contrib/Google_PlusService.php'; 
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php'; 

session_start(); 

$client = new Google_Client(); 
$client->setApplicationName("My app"); 
$client->setApprovalPrompt (auto); //prompt consent screen only for first time 

//*********** Replace with Your API Credentials ************** 
$client->setClientId('xxx.apps.googleusercontent.com'); 
$client->setClientSecret('xxx'); 
$client->setRedirectUri('http://example.com/oauth2callback'); 
$client->setDeveloperKey('xxx'); 
//************************************************************ 

$client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email')); 
$client->refreshToken(file_get_contents('refreshtoken.conf')); //retrieve refresh_token from file 
$client->setAccessToken("refresh_token"); // I guess something is wrong here. I am trying to pass the refresh token to get a new access token but not sure if this is correct 
$client->authenticate(); //after that authenticate user 
$plus = new Google_PlusService($client); 
$oauth2 = new Google_Oauth2Service($client); // Call the OAuth2 class for get email address 

if (isset($_REQUEST['logout'])) { 
    unset($_SESSION['access_token']); 
} 

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

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

if ($client->getAccessToken()) { 
    $user = $oauth2->userinfo->get(); 
    $me = $plus->people->get('me'); 
    $email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2 

    $optParams = array('maxResults' => 100); 
    $activities = $plus->activities->listActivities('me', 'public', $optParams); 

    $jsonarray = json_decode($client->getAccessToken()); 
    $arrGoogleAuth['access_token']=$jsonarray->access_token; 
    $arrGoogleAuth['refresh_token']=$jsonarray->refresh_token; 
    //filewrite 

    $myFile = "refreshtoken.conf"; 
    $fh = fopen($myFile, 'w') or die("can't open file"); //write the json into refresh.conf 
    fwrite($fh, $client->getAccessToken()); 
    fclose($fh); 

    $_SESSION['access_token'] = $client->getAccessToken(); 
} else { 
    $authUrl = $client->createAuthUrl(); 
} 
?> 

回答

1

而不在PHP客戶端庫的專家,看它的代碼,我相信你的代碼的以下子集/細微的變化應該是足夠了(假設你以前已經成功請求離線訪問,回來刷新令牌和持續的$client->getAccessToken()輸出)(應該是一個JSON對象):

require_once 'google-api-php-client/src/Google_Client.php'; 
require_once 'google-api-php-client/src/contrib/Google_PlusService.php'; 
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php'; 

session_start(); 

$client = new Google_Client(); 
$client->setApplicationName("My app"); 
$client->setClientId('xxx.apps.googleusercontent.com'); 
$client->setClientSecret('xxx'); 
$client->setRedirectUri('http://example.com/oauth2callback'); 
$client->setDeveloperKey('xxx'); 

$client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email')); 

$client->setAccessToken(file_get_contents('refreshtoken.conf')); 
$plus = new Google_PlusService($client); 
$oauth2 = new Google_Oauth2Service($client); 

基本的$client->getAccessToken()輸出包括一個訪問令牌,刷新令牌(如果授予),時間以實時信息等假設你堅持這個JSON blob,然後設置它,你可以繼續使用Google_PlusService(以及其他Google API) - 它們將自動檢查訪問令牌是否已過期,並根據需要使用刷新令牌獲取新的訪問令牌。

+0

嗨,aeijdenberg。按照您的建議,刷新令牌將用於從Google服務器交換訪問令牌。我現在還有一個問題,每個登錄到我的系統的用戶都會使用我的帳戶登錄,因爲我喜歡將我的刷新令牌硬編碼到程序中。 有沒有什麼建議可以讓每個用戶都有自己的刷新標誌?我認爲我將它保存在refreshtoken.conf中的想法並不是正確的方法。 –

+0

正確 - 你不應該把它存儲在refreshtoken.conf中 - 我以爲是測試。您需要將其保存在適用於您的應用程序的任何數據庫/存儲系統中。如果您不需要實際具有脫機訪問權限(用戶不在場時訪問),則可以請求訪問令牌並將其存儲在用戶會話中,而不是簡單的。我不是PHP專家,所以我不能給你最好的指導如何做到這一點。 – aeijdenberg

+0

我其實不需要離線訪問。我試圖將訪問令牌存儲在會話中。不知何故,訪問令牌將在一小時內過期,那麼用戶將無法訪問已經存在的訪問令牌,以便他們首先清除瀏覽緩存以便再次登錄。任何建議?再次感謝,男士。 –

1
if ($client->getAccessToken()) { 

    if($client->isAccessTokenExpired()) { 

    $client->authenticate(); 
    $NewAccessToken = json_decode($client->getAccessToken()); 
    $client->refreshToken($NewAccessToken->refresh_token); 

    } else { 

     $user = $oauth2->userinfo->get(); 
     $me = $plus->people->get('me'); 
     $email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2 

     $optParams = array('maxResults' => 100); 
     $activities = $plus->activities->listActivities('me', 'public', $optParams); 

     $_SESSION['access_token'] = $client->getAccessToken(); 
    } 
} else { 
    $authUrl = $client->createAuthUrl(); 
} 
相關問題