1

最初的任務非常簡單:從Google+信息頁獲取最新信息。如何在服務器應用程序中登錄Google API並使用Google Plus?

現在需要3天的時間才能發現互聯網上的所有示例似乎都過時或錯誤或無效。 Google開發人員文檔也沒有提供太多幫助,每個新的令人困惑的文檔頁面都越來越複雜。所以,夥計們,我放棄了。

首先,我嘗試實施OAuth 2.0程序,該程序記錄在他們的文檔(https://developers.google.com/identity/protocols/OAuth2WebServer)中。正如其標題所暗示的那樣,恰恰是從服務器應用程序連接。我跟着它,乍一看,它的工作原理:我接到了回電,成功通過驗證,獲取訪問令牌並將其存儲並進行簡單調用以獲取帖子。

// Initialization 

$this->googleClient = new Google_Client(); 
$this->googleClient->setAuthConfig(Json::decode($config->get('client_json'))); 
$this->googleClient->setAccessType('offline'); 
$this->googleClient->setIncludeGrantedScopes(TRUE); 
$this->googleClient->addScope('https://www.googleapis.com/auth/plus.me'); 
$this->googleClient->setRedirectUri(Url::fromRoute('mymodule.gplus.callback')->setAbsolute()->toString()); 

// The callback 

$client->authenticate($code); 
$accessToken = $client->getAccessToken(); 

(這似乎傻了這裏唯一的東西 - 是的範圍,我不知道我應該要求什麼餘地,如果我只是需要讀取公共頁面的公開信息,所以我就選擇了第一。 。這看上去與隨機條目)

正如我所說的,我得到了令牌,並可能獲取我的帖子:

// Using Google_Service_Plus 

$this->client()->setAccessToken($access_token); 
$this->googleServicePlus = new Google_Service_Plus($this->client($reset)); 
$this->googleServicePlus->activities->listActivities($endpoint, 'public', ['maxResults' => 1]); 

但1小時後,它只是停止工作,聲稱令牌是過時或東西,它需要被刷新。而這裏就是最好的例子:我找不到刷新令牌的方法。 $response from authenticate()不再返回刷新標記(儘管在其他答案中已多次提及),所以我甚至沒有辦法刷新它。

我試着在圖書館挖掘(從我composer.json"google/apiclient": "^2.0"),並想通了,authenticate()方法實際上是不贊成有這似乎與代幣玩一些其他的方法。我試圖\Google_Client::fetchAccessTokenWithAssertion()這問一些應用默認憑據 ...這使我們在這裏描述的完全不同的主題和認證方式:https://developers.google.com/identity/protocols/OAuth2ServiceAccount

所以我應該放棄,我所做的一切,現在實行新的東西?我怎麼能做這個獲取新聞的簡單任務?

很抱歉的長期問題。

回答

0

您所關注的過程很好。您遇到的問題是刷新令牌。雖然官方文件指出:

如果你使用谷歌的API客戶端庫,該客戶對象刷新根據需要,只要你配置脫機訪問該對象的訪問令牌。

它沒有解釋如何使用PHP客戶端庫進行操作。這對我來說也是一個問題,所以這是我採取的方法,並希望它可以幫助你。

// 1. Build the client object 
$client = new Google_Client(); 
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/index.php'); 
$client->setAuthConfig("client_secret.json"); 
$client->addScope($scopes); 
$client->setAccessType("offline"); 

我通常會將Access Token保存到會話中,因此在繼續之前,我會檢查訪問令牌是否已保存到會話中。如果是,那麼我繼續檢查訪問令牌是否已經過期。如果是,則我繼續刷新訪問令牌,然後繼續進行API調用。

// 2. Check if the access token is already saved to session 
if(isset($_SESSION["access_token"]) && ($_SESSION["access_token"])) { 

    //set access token before checking if already expired 
    $client->setAccessToken($_SESSION["access_token"]); 

    //check if access token is already expired and refresh if so 
    if ($client->isAccessTokenExpired()) { 
     $refreshToken = $_COOKIE["refresh_token"]; //get refresh token 
     $client->refreshToken($refreshToken); // refresh the access token 
    } 

    //get new access token and save it to session 
    $_SESSION['access_token'] = $client->getAccessToken(); 

    // set access token after checking if already expired 
    $client->setAccessToken($_SESSION["access_token"]); 

    $plusService = new Google_Service_Plus($client); 

    $optParams = array(
     "maxResults" => 5, 
     "pageToken" => null 
    ); 

    $activitiesList = $plusService->activities->listActivities("+cnn", "public", $optParams); 

    $activities = $activitiesList->getItems(); 

    foreach ($activities as $activity) { 
     print_r($activity); 
     print "<br>**********************<br>"; 
    } 


} 

如果訪問令牌不保存到會話,這意味着身份驗證和授權並沒有發生,所以我開始對用戶進行認證。

// 3. Authenticate user since access token is not saved to session 
else { 

    if(!isset($_GET["code"])){ //get authorization code 

    $authUrl = $client->createAuthUrl(); 
    header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL)); 

    } else { //exchange authorization code for access token 

    $client->authenticate($_GET['code']); //authenticate client 

    //get access token and save it to session 
    $_SESSION['access_token'] = $client->getAccessToken(); 

    //save refresh token to a Cookie 
    $refreshToken = $_SESSION["access_token"]["refresh_token"]; 
    setcookie("refresh_token", $refreshToken, time() + (86400 * 30), "/"); 

    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/index.php'; 
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); 

    } 

} 

請注意:出於演示的目的,我節省了刷新令牌在這個例子中一個cookie;但是,衆所周知,您不應該將此信息保存到cookie中,而是保存到安全的數據庫中。此外,authenticate()方法不被棄用,它只是方法fetchAccessTokenWithAuthCode()的別名。另一件事,你正在使用的範圍不,因爲你是獲取從公共頁面信息,根據文檔herehere,我直覺,我應該只允許訪問知道你在谷歌誰https://www.googleapis.com/auth/plus.me

相關問題