【问题标题】:Google plus cross site identity Android to PHP access tokenGoogle plus 跨站身份 Android 转 PHP 访问令牌
【发布时间】:2013-11-02 13:28:21
【问题描述】:

我有一个客户端和服务器应用程序,一旦在客户端 (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+ 客户端

【问题讨论】:

    标签: android google-api google-plus google-oauth


    【解决方案1】:

    你读过Server-side access for your app documentation吗?

    您需要的是一次性授权代码,您将其传递给您的服务器,然后服务器将该授权代码交换为自己的访问和刷新令牌。 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 传递给您的服务器。请参阅line 98 in the PHP quick-start,了解如何使用 PHP 客户端库执行代码交换(以及验证 ID 等其他步骤)。您还需要配置 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());
    

    【讨论】:

    • 肯定越来越近了,我更新了php sdk。似乎现在我可以为每个“代码”发出 1 个请求。随后的调用中,我不断收到关于身份验证的无效授权错误。我添加了一些 php 代码。
    • “代码”只能使用一次……这就是重点。您必须将其交换为访问令牌(如果您需要长期访问,还需要刷新令牌)。访问令牌在有效时为您的客户端提供 API 访问权限。当它们过期时,您可以使用刷新令牌来获取新的访问令牌。 PHP 客户端库可以轻松地为您处理这个问题,请阅读更多关于这些文档的内容。您必须在服务器上存储访问令牌和刷新令牌,然后将它们用于后续请求,您不应该为用户的每个连接执行代码交换。
    • 确保在将令牌传递给您的服务器后都调用 `GoogleAuthUtils.invalidateToken()' developer.android.com/reference/com/google/android/gms/auth/…, java.lang.String) 否则用户将无法注销并再次登录克+。 GoogleAuthUtil javadoc 中的示例developer.android.com/reference/com/google/android/gms/auth/…
    • 请问这里为什么使用new apiClient()?我只看到new Google_Client() 这是来自新 SDK 的最后一个?
    • @BrettJ 嗨,什么会代替 appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES, "&lt;app-activity1&gt; &lt;app-activity2&gt;"); app-activity1 , app-activity2 ?你能告诉我吗?
    【解决方案2】:

    如果你关心 ID Tokens,开始阅读的地方可能在这里:https://developers.google.com/accounts/docs/OAuth2Login

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

    【讨论】:

      猜你喜欢
      • 2013-01-17
      • 1970-01-01
      • 2014-07-08
      • 2017-04-29
      • 2019-04-28
      • 2021-10-09
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多