I have a client and server app that needs to access a users g+ profile after on the SERVER side once they've validated on the client (android)
I'm gettin an ID token on the client side by this
@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);
}
}
Which will give me a long ID token as described in this blog http://www.tbray.org/ongoing/When/201x/2013/04/04/ID-Tokens
I think I'm supposed to send that token to my server where I need to do something to turn it into an access_token. I can verify that the id token? is good by sending a curl request to
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=
which gives back a json string like this
{
"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 server
\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);
where the issued_to is my client id for the Android app in the Google APIs console and the audience is the client is of my web app, seems right so far I think.
So now I'm using the php client and not really sure what to do from there. I tried to validate the api client using the id token but I just get the error 400 - Error fetching OAuth2 access token, message: 'invalid_grant'
I'm not sure if I'm supposed to try to authenticate the PHP Google+ client using that ID token or some how exchange it for an access token
An ID token is available when a Credential object's user ID matches the user ID of a Google account that is signed in on the device. To sign in with an ID token, first retrieve the ID token with the getIdTokens method. Then, send the ID token to your app's backend.
The id_token is used in OpenID Connect protocol, where the user is authenticated as well as authorized. (There's an important distinction between authentication and authorization.) You will get id_token and access_token. The id_token value contains the information about the user's authentication.
Did you read the Server-side access for your app documentation?
What you need is a one-time authorization code that you pass to your server and the server exchanges that authorization code for its own access and refresh tokens. The ID tokens are useful for verifying that the app and user are who they say they are, but not for getting your server access to data.
Your code is close, but is missing some key parts to make this work, such as specifying the app activity types that your app initially requested in the PlusClient configuration, and your scopes string needs a change.
Taken from the docs:
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);
}
The code
that you get back, you pass to your server. See line 98 in the PHP quick-start for how to perform the code exchange (and other steps like verifying the ID) using the PHP client library. You'll also need to configure your PHP client for offline access. The basics are:
$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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With