2

I can't get an offline access token with this code... Why ?

$client = new Google_Client();
$client->setApplicationName('MyAppName');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me'));
$client->setClientId('MyCientID');
$client->setClientSecret('MyClientSecret');
$client->setRedirectUri('http://mydomain.com/googlecallback');
$client->setApprovalPrompt('force');
$client->setAccessType('offline');
$client->setDeveloperKey('MyDeveloperKey');
$plus = new Google_Service_Plus($client);
header('Location: '.$client->createAuthUrl());

This is redirect to the google login page, which ask only for an 1hour access token... I'm lost in the dark...

Thanks a lot!

EDIT :

here is my login page code :

$client = new Google_Client();
$client->setClientId('qvdsfvqdsf');
$client->setClientSecret('qsdfvqsdf');
$client->setRedirectUri('?a=callback');
$client->setDeveloperKey('qdcQSDCQSD');
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me'));
$plus = new Google_Service_Plus($client);

if($_GET['a'] == 'authorize'){
    header('Location: '.$client->createAuthUrl());
}
elseif($_GET['a'] == 'callback' && isset($_GET['code']) && !isset($_GET['error'])){
    $client->authenticate($_GET['code']);
    if($client->getAccessToken()){
        STORE ACCESS TOKEN
    }
}

And my API usage :

$client = new Google_Client();
$client->setClientId('qsdfsqd');
$client->setClientSecret('qsdfqsd');
$client->setRedirectUri('qdfq');
$client->setDeveloperKey('sdfvsdf');
$client->setApprovalPrompt('auto');
$client->setAccessType('offline');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me'));
$plus = new Google_Service_Plus($client);
$client->setAccessToken('STORED ACCESS TOKEN');
$activities = $plus->activities->listActivities('me', 'public', array('maxResults'=>10));

What I am doing wrong ?

Deptroco
  • 129
  • 1
  • 3
  • 11

3 Answers3

1

You need to have the "http://mydomain.com/googlecallback" URL set as a redirect URI on the application settings page.

The $client->createAuthUrl() method creates the URL to the authentication page. After going to that page and authorizing the application, Google will redirect you back to /googlecallback with a query string param called 'code', which you should pass to the authenticate() method of the client. Only then you'll have access to the token.

Something like this (assuming this is on /googlecallback):

$client = new Google_Client();

$client->setApplicationName('MyAppName');
$client->setScopes(array('https://www.googleapis.com/auth/plus.me'));
$client->setClientId('MyCientID');
$client->setClientSecret('MyClientSecret');
$client->setRedirectUri('http://mydomain.com/googlecallback');
$client->setApprovalPrompt('force');
$client->setAccessType('offline');
$client->setDeveloperKey('MyDeveloperKey');

if (empty($_GET['code'])) {
    header('Location: '.$client->createAuthUrl());
} else {
    $client->authenticate($_GET['code']);
    $access_token = $client->getAccessToken();
    // save the token somewhere so you can use later
    // without having to go to the auth page again
}
Vinicius Braz Pinto
  • 8,209
  • 3
  • 42
  • 60
  • Im already doing that, but this gave me a 1hour access token, i want a permanant access token... but thanks you're great! – Deptroco Mar 08 '14 at 14:46
  • Ah ok, sorry. But there's no permanent token, the first time you get the token + a refresh token. Then after that the new library (1.x) auto refreshes the token for you when it expires. https://developers.google.com/accounts/docs/OAuth2WebServer – Vinicius Braz Pinto Mar 08 '14 at 15:06
  • You got an exemple ? x) – Deptroco Mar 08 '14 at 15:07
  • There's no extra code, the one I posted should work fine. The first time a user authorizes your app, his access token will contain a "refresh_token" field. You don't need to do anything, the lib handles it. If you're not getting the refresh token, check this question http://stackoverflow.com/questions/10827920/google-oauth-refresh-token-is-not-being-received – Vinicius Braz Pinto Mar 08 '14 at 15:14
  • getAccessToken output : {"access_token":"random","token_type":"Bearer","expires_in":3600,"id_token":"random","refresh_token":"random","created":1394292095} But it expire after 1hour ! i call setAccessToken() to use the API Thanks thanks thanks !! – Deptroco Mar 08 '14 at 15:23
  • You finally helped me to find the answer, thanks a lot! – Deptroco Mar 09 '14 at 00:36
  • great! just a note, I said in a previous comment that you don't need to do anything about the refresh token, but you obviously need to save it again locally otherwise you'll keep sending the expired token and i think the API limits the number of refresh tokens you get – Vinicius Braz Pinto Mar 09 '14 at 04:02
  • So if i undertood you, after 2 hour, the user must be redirected to the oauth login page ? – Deptroco Mar 09 '14 at 10:29
  • No, you just send the token you have saved earlier. Check the docs: https://developers.google.com/accounts/docs/OAuth2WebServer – Vinicius Braz Pinto Mar 09 '14 at 15:57
  • Your awesome, thanks for all your replies!! I just edited my question, with the exact usage of the API, what I am doing wrong ? thanks :) – Deptroco Mar 09 '14 at 16:27
0

Finally got the answer :

Using $client->setApprovalPrompt('force'); was blocking the normal Google token refresh process, while $client->setApprovalPrompt('auto'); do it like a charm.

Thanks.

Deptroco
  • 129
  • 1
  • 3
  • 11
  • Happy you're working OK, but this is not the answer. There was some other problem that got solved, and this code change is just coincidence. – pinoyyid Mar 09 '14 at 04:02
0

If a user has previously authenticated against the ClientID without requesting offline mode, and you then request offline mode, it wont give you the refresh token.

The user needs to de-authorize themselves from app and then re-authorize once the app will request offline mode.

Prisoner
  • 49,922
  • 7
  • 53
  • 105