Kelly Larsen
Kelly Larsen

Reputation: 973

google oauth2/calendar getRefreshToken returning NULL

I'm trying to allow users to link their google calendar to my system, I've got it mostly working, and actually had it working for a while, but trying to make some modifications it's broken again :(

this page sends them to google:

require_once '../../resources/apis/google-api-php-client-2.2.1/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('../../resources/apis/google-api-php-client-2.2.1/client_secret.json');
$client->setAccessType("offline");        // offline access
$client->setIncludeGrantedScopes(true);   // incremental auth
$client->addScope(Google_Service_Calendar::CALENDAR);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/sync/admin/apicomms/gcalmaster/syncFromGoogleCallback.php');
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Then the callback goes to here:

require_once '../../resources/apis/google-api-php-client-2.2.1/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('../../resources/apis/google-api-php-client-2.2.1/client_secret.json');
$client->setAccessType("offline");        // offline access
$client->setIncludeGrantedScopes(true);   // incremental auth
$client->addScope(Google_Service_Calendar::CALENDAR);
//$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/sync/admin/broadcast/syncFromGoogleCallback.php');
$client->authenticate($_GET['code']);

$refresh_token = $client->getRefreshToken();

var_dump($_GET);
var_dump($refresh_token);

The callback page is showing

array(2) { ["code"]=> string(89) "x/xxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ["scope"]=> string(40) "https://www.googleapis.com/auth/calendar" } NULL

So it seems that the authentication is going smoothly, it's not throwing any errors...

What am I missing that is causing me to not get a refresh token? I've checked multiple times under https://myaccount.google.com/permissions to make sure my app isn't currently listed.

EDIT:

I have another script in my app which is currently working, it does the actual synchronisation, pulling the refresh token from the database, getting an access token with it, and succesfully pulling events from the calendar API. The thing that's not currently working is the 'adding' of new calendars to my app, the process of getting a refresh token from a new user

$refreshToken = $db->execute('pull refresh token from db');
require_once '../../resources/apis/google-api-php-client-2.2.1/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig('../../resources/apis/google-api-php-client-2.2.1/client_secret.json');
$client->fetchAccessTokenWithRefreshToken($refreshTokenFromDB);
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
    'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);

if (count($results->getItems()) == 0) {
    print "No upcoming events found.\n";
} else {
    //loop through stuff
}

Upvotes: 1

Views: 1004

Answers (1)

Joseph_J
Joseph_J

Reputation: 3669

You are close.

So it looks like you are successful in obtaining an authorization code.

Then with your authorization code you use the:

$client->authenticate($_GET['code']);  

Keep in mind this is not a token. It is an authorization code.

You now have to request a access token using the authorization code.

$accessToken = $client->getAccessToken();

It's been awhile since I've tinkered around with this, but I think that this is also your only time that you will be able to request a refresh token.

So you will want to do this line next:

 $refreshToken = $client->getRefreshToken();

You will want to securely save these tokens in a json file somewhere on your system to use the next time you want to do something with this calendar.

So when you do use this again, you will use the $accessToken to establish your credentials with google. If that access token is expired you will have to use the refresh token to get a new access token. I'm pretty sure the refresh token stays constant. If not it will be sent with the new access token. Then you re-save the json file. Rinse and repeat.

UPDATED

You will use:

$client->fetchAccessTokenWithRefreshToken($refresh_token);

To obtain a new access token.

Upvotes: 1

Related Questions