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

相关问题