我正在下面的链接中跟踪这些文档:
具体来说,这部分说:
如果不需要脱机访问,则可以检索访问令牌并通过安全连接将其发送到服务器。您可以使用GoogleAuthUtil.getToken()直接获得访问令牌,方法是在没有服务器的OAuth 2.0客户端ID的情况下指定作用域。
我检索访问令牌如下:
accessToken = GoogleAuthUtil.getToken(
AuthenticatorActivity.this,
Plus.AccountApi.getAccountName(Common.mGoogleApiClient),
"oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login email"
);
在检索访问令牌之后,我将其发送到web服务器,在web服务器上,我可以通过调用
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token']
上面的请求返回android应用程序客户端id,它也正确地返回用户电子邮件。
问题是,当我尝试运行$client->authenticate($_POST'google_access_token');时,我会得到一个异常:"invalid_grant:不正确的令牌类型“。
为了防止getToken缓存,我总是在android中使令牌失效:
if (accessToken != null && !accessToken.isEmpty()) {accessToken accessToken);}
下面是php代码:
if (!isset($_POST['google_access_token'])) {
throw new Exception('missing google_access_token');
}
$client = new \Google_Client();
$client->setApplicationName("GiverHub");
$client->setClientId($this->config->item('google_client_id'));
$client->setClientSecret($this->config->item('google_client_secret'));
$client->setDeveloperKey($this->config->item('google_developer_key'));
$client->setRedirectUri($this->config->item('google_redirect_uri'));
$client->setScopes([
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.me',
'email',
]);
try {
$client->authenticate($_POST['google_access_token']); // if i remove this the rest of the code below works! ...
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token'];
$req = new \Google_Http_Request($reqUrl);
$io = $client->getIo();
$response = $io->executeRequest($req);
$response = $response[0];
$response = json_decode($response, true);
if ($response === null) {
throw new Exception('Failed to check token. response null');
}
if ($response['issued_to'] !== '466530377541-s7cfm34jpf818gbr0547pndpq9songkg.apps.googleusercontent.com') {
throw new Exception('Invalid access token. issued to wrong client id: '. print_r($response, true));
}
if (!isset($response['user_id'])) {
throw new Exception('Missing user_id');
}
if (!isset($response['email'])) {
throw new Exception('Missing email');
}
/** @var \Entity\User $user */
$user = Common::create_member_google([
'id' => $response['user_id'],
'email' => $response['email'],
'given_name' => '',
'family_name' => '',
]);
$user->login($this->session);
if ($user instanceof \Entity\User) {
echo json_encode( [ 'success' => true, 'user' => $user ] );
} else {
echo json_encode( [ 'success' => false, 'msg' => $user ] );
}
} catch(Exception $e) {
echo json_encode(['success' => false, 'msg' => $e->getMessage()]);
}
如果我删除$client->authenticate();行.问题是我不能得到given_name / family_name等等。只有电子邮件/ google_user_id从令牌信息..。
对于为什么密钥对tokeninfo有效,而不用于身份验证,有什么想法吗?
我试过许多不同的范围。服务器端和android端。
发布于 2014-12-01 15:56:01
这是在user158443建议我使用$client->setAccessToken()之后,我想出的解决方案;
// first json_encode the access token before sending it to $client->setAccessToken();
$json_encoded_access_token = json_encode([
'access_token' => $_POST['google_access_token'],
'created' => time(), // make up values for these.. otherwise the client thinks the token has expired..
'expires_in' => time()+60 // made up a value in the future...
]);
// and then set it
$client->setAccessToken($json_encoded_access_token);
// and then get userinfo or whatever you want from google api !! :)
$oauth2 = new \Google_Service_Oauth2($client);
$user_info = $oauth2->userinfo->get();
注意:--如果你是在生产中的话,“模仿”expires_in并创建它可能是不明智的。你应该先打电话给tokeninfo,然后从那里得到过期的时间.
注意:我仍然不知道如何获得这个刷新令牌.但我不需要用用例。
发布于 2014-11-29 14:05:31
$client->authenticate()
方法并不完全完成您想要做的事情。它从早期的OAuth事务中获取一次代码,并将其交换为访问令牌。在你的情况下-你是说你已经有了访问令牌。
您应该能够调用$client->setAccessToken()
来设置令牌,因此它可能如下所示
$client->setAccessToken($_POST['google_access_token']);
https://stackoverflow.com/questions/27200360
复制相似问题