6

我有一个客户端和服务器应用程序,一旦在客户端(android)上验证后,需要在服务器端访问用户 g+ 配置文件

我通过这个在客户端获得了一个 ID 令牌

@Background
void getAccessToken() {


    String scopes = "audience:server:client_id:xxxxxxxxxxxxx.apps.googleusercontent.com";

    Log.d(TAG,scopes);

    try {

        accessToken = GoogleAuthUtil.getToken(this,mPlusClient.getAccountName(),scopes);

        Log.d(TAG,accessToken);

        getPlusFriends();

    }
    catch (IOException transientEx) {
        Log.e(TAG, transientEx.getMessage());
        return;
    }
    catch (UserRecoverableAuthException e) {
        Log.e(TAG, e.getMessage());
        accessToken = null;
    }
    catch (GoogleAuthException authEx) {
        Log.e(TAG, authEx.getMessage());

        return;
    }
    catch (Exception e) {
        throw new RuntimeException(e);
    }
}

这将给我一个长 ID 令牌,如本博客http://www.tbray.org/ongoing/When/201x/2013/04/04/ID-Tokens中所述

我想我应该将该令牌发送到我的服务器,在那里我需要做一些事情将它变成一个 access_token。我可以验证 id 令牌吗?发送 curl 请求到

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=

它返回一个像这样的json字符串

{
"issuer": "accounts.google.com",
"issued_to": "xxxxxxxxxxxxxx.apps.googleusercontent.com",
"audience": "xxxxxxxxxxxxxx.apps.googleusercontent.com",
"user_id": "123456",
"expires_in": 3362,
"issued_at": 1382577073,
"email": "myemail@something",
"verified_email": true
}

php服务器

\Config::load('google_api', 'google');

 $key = Config::get('google.client_id');
 $secret = Config::get('google.client_secret');
 $scopes = Config::get('google.scopes');

 $client = new Google_Client();

 $client->setClientId($key);
 $client->setClientSecret($secret);
 $client->setScopes($scopes);
 $client->setState('offline');
 $client->authenticate($token);

其中issued_to 是我在Google API 控制台中的Android 应用程序的客户端ID,而受众是我的Web 应用程序的客户端,我认为到目前为止似乎是正确的。

所以现在我正在使用 php 客户端,并不确定从那里做什么。我尝试使用 id 令牌验证 api 客户端,但我只收到错误 400 - 获取 OAuth2 访问令牌时出错,消息:'invalid_grant'

我不确定是否应该尝试使用该 ID 令牌对 PHP Google+ 客户端进行身份验证,或者如何将其交换为访问令牌

4

2 回答 2

5

您是否阅读了应用程序文档的服务器端访问

您需要的是一个一次性授权代码,您将其传递给您的服务器,然后服务器将该授权代码交换为它自己的访问和刷新令牌。ID 令牌可用于验证应用程序和用户是否是他们所说的身份,但不适用于让您的服务器访问数据。

您的代码很接近,但缺少一些使这项工作正常工作的关键部分,例如指定您的应用最初在 PlusClient 配置中请求的应用活动类型,并且您的范围字符串需要更改。

取自文档:

Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
          "<app-activity1> <app-activity2>");
String scopes = "oauth2:server:client_id:<server client-id>:api_scope:<scope1> <scope2>";
String code = null;
try {
  code = GoogleAuthUtil.getToken(
    this,                             // Context context
    mPlusClient.getAccountName(),     // String accountName
    scopes,                           // String scope
    appActivities                     // Bundle bundle
  );

} catch (IOException transientEx) {
  // network or server error, the call is expected to succeed if you try again later.
  // Don't attempt to call again immediately - the request is likely to
  // fail, you'll hit quotas or back-off.
  ...
  return;
} catch (UserRecoverableAuthException e) {
  // Recover
  code = null;
} catch (GoogleAuthException authEx) {
  // Failure. The call is not expected to ever succeed so it should not be
  // retried.
  ...
  return;
} catch (Exception e) {
  throw new RuntimeException(e);
}

你得到的code,你传递给你的服务器。有关如何使用 PHP 客户端库执行代码交换(以及验证 ID 等其他步骤)的信息,请参阅PHP 快速入门中的第 98 行。您还需要配置 PHP 客户端以进行离线访问。基本情况是:

$client = new apiClient();
$client->setClientId('From APIs console');
$client->setClientSecret('From APIs console');
$client->setScopes('exact same list of scopes as Android app, space separated');
$client->setRedirectUri('postmessage');  // Used in hybrid flows
$client->setState('offline');
// Exchange authorization code for access and refresh tokens
$client->authenticate($code);
$token = json_decode($client->getAccessToken());
于 2013-10-24T14:13:30.560 回答
0

如果您关心 ID 令牌,可以从这里开始阅读:https ://developers.google.com/accounts/docs/OAuth2Login

但是,如果您尝试访问某人的 G+ 个人资料并且您在 PHP 领域,请查看https://developers.google.com/+/quickstart/php上的 PHP 快速入门- 这可能更容易比你想象的。

于 2013-10-24T07:55:13.243 回答