如何在服务器应用程序中登录Google API并使用Google Plus?
最初的任务非常简单:从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
所以我应该放弃,我所做的一切,现在实行新的东西?我怎么能做这个获取新闻的简单任务?
很抱歉的长期问题。
您所关注的过程很好。您遇到的问题是刷新令牌。虽然官方文件指出:
如果你使用谷歌的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()
的别名。另一件事,你正在使用的范围不傻,因为你是获取从公共页面信息,根据文档here和here,我直觉,我应该只允许访问知道你在谷歌谁https://www.googleapis.com/auth/plus.me
。