将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后,对其进行身份验证
我正在以下链接中查看文档: 特别是说: 如果不需要脱机访问,可以检索访问令牌并通过安全连接将其发送到服务器。您可以直接使用GoogleAuthUtil.getToken()获取访问令牌,方法是在不使用服务器OAuth 2.0客户端ID的情况下指定作用域。例如: 我检索访问令牌,如下所示:将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后,对其进行身份验证,php,android,google-plus,google-oauth,google-api-php-client,Php,Android,Google Plus,Google Oauth,Google Api Php Client,我正在以下链接中查看文档: 特别是说: 如果不需要脱机访问,可以检索访问令牌并通过安全连接将其发送到服务器。您可以直接使用GoogleAuthUtil.getToken()获取访问令牌,方法是在不使用服务器OAuth 2.0客户端ID的情况下指定作用域。例如: 我检索访问令牌,如下所示: accessToken = GoogleAuthUtil.getToken( AuthenticatorActivity.this,
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($\u POST['google\u access\u token');我收到一条异常消息:“无效的授权:不正确的令牌类型”
为了防止getToken缓存,我总是在android应用程序中使令牌无效:
if(accessToken!=null&&!accessToken.isEmpty()){
GoogleAuthUtil.invalidateToken(AuthenticatorActivity.this,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(),上面的代码就可以工作;线问题是我无法获得给定的姓名/姓氏等。。仅来自tokeninfo的电子邮件/谷歌用户id
有没有想过为什么密钥适用于令牌信息而不适用于身份验证
我试过许多不同的示波器。。无论是在服务器端还是android端,
$client->authenticate()
方法都无法完成您想要完成的任务。它从早期的OAuth事务中获取一次性代码,并将其交换为访问令牌。在您的情况下,您是说您已经拥有访问令牌
您应该能够调用$client->setAccessToken()
来设置令牌,因此它看起来像
$client->setAccessToken($_POST['google_access_token']);
这是我在user158443建议我使用$client->setAccessToken()后提出的解决方案 注意:如果您正在生产中,“模仿”我刚刚创建的expires\u可能并不明智。。。您可能应该首先调用tokeninfo并从那里获取过期时间
注意:我仍然不知道如何为此获取刷新令牌。。。但是我的用例不需要一个。谢谢你的回复。。。我已经尝试了您的建议,使用$client->setAccessToken();好几次。它不起作用$client->setAccessToken()需要一个json格式的字符串。。它还需要一个访问令牌和一个刷新令牌。。我不知道如何将androids getToken()生成的访问令牌转换为$client->setAccessToken()可以接受的json字符串引发异常,并显示以下消息:无法对令牌进行json解码。我通过基于$_POST['google_access_token']创建json字符串,然后调用$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();