16

I am using the google Calendar API. This is what I want, once you give the app the permission, I can always use the app, without the need of giving access everyday. I keep hearing that I need to save the access token or use the refresh token to do what I want to do.. Here is the thing, how do you do it? How does the code look like? I've tried saving the token in a cookie, but after an hour, the access token has expired. How do I keep the user logged in?

PS: Please give me code examples with explanations.

Here is my code (using CakePHP):

$client = new Google_Client();

    $client->setApplicationName("Wanda3.0 Agenda");

    $cal = new Google_CalendarService($client);

    if (isset($_GET['code'])) {

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


        $_SESSION['token'] = $client->getAccessToken();


        header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);

    }

    if (isset($_SESSION['token'])) { $client->setAccessToken($_SESSION['token']); }

if ($client->getAccessToken()) {
        /************* Code entry *************/


    }else{
        /************* Not connected to google calendar code *************/
        $authUrl = $client->createAuthUrl();

        $returnArr = array('status' => 'false', 'message' => "<a class='login' href='$authUrl'>Connect Me!</a>");

        return $returnArr;

    }
IPV3001
  • 272
  • 3
  • 16
hope_industries
  • 463
  • 1
  • 5
  • 12
  • The access token expires - that's why you get a refresh token. You should be able to get a new access token(and updated refresh token) using the refresh token you get when authenticating. (I don't have any code examples for you though, unfortunately) – Terry Seidler Sep 21 '12 at 12:47
  • (however, only use the refresh token if the original access token has expired: http://stackoverflow.com/a/10186904/1313164) – Terry Seidler Sep 21 '12 at 12:50
  • @TerrySeidler In theory I know what to do, or atleast this is what I understand so far: When the acces token expires, I am suppose to use the refresh token to get a new one, but the big question is how to do it in practice. – hope_industries Sep 21 '12 at 13:00
  • I see! You could try the last comment on this page, seems to have worked for that guy: http://code.google.com/p/google-api-php-client/issues/detail?id=94 – Terry Seidler Sep 21 '12 at 13:09
  • Checked what you have send and applied it, waited an hour and its still logged in! My final test is to wait a few days and see if its still logged in. Props of awesomeness to @TerrySeidler if its still works! I'll answer the question within a few days! – hope_industries Sep 21 '12 at 15:44

3 Answers3

15

Ok, after waiting for a few days, the suggestion from Terry Seidler(comments below) made it all happen! Here is my piece of code on how to automaticly refresh the access token without autenticating each time using cookies.

(NOTICE: It's safer to save the refresh token in your database)

This is the magic (using cookies):

$client = new Google_Client();

    $client->setApplicationName("Wanda3.0 Agenda");

    $cal = new Google_CalendarService($client);

    $client->setAccessType('offline');

    if (isset($_GET['code'])) {

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

        $_SESSION['token'] = $client->getAccessToken();

        header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);

    }

    //Where the magic happends
    if (isset($_SESSION['token'])) {

        //Set the new access token after authentication
        $client->setAccessToken($_SESSION['token']);

        //json decode the session token and save it in a variable as object
        $sessionToken = json_decode($_SESSION['token']);

        //Save the refresh token (object->refresh_token) into a cookie called 'token' and make last for 1 month
        $this->Cookie->write('token', $sessionToken->refresh_token, false, '1 month');
    }

    //Each time you need the access token, check if there is something saved in the cookie.
    //If $cookie is empty, you are requested to get a new acces and refresh token by authenticating.
    //If $cookie is not empty, you will tell the client to refresh the token for further use,
    // hence get a new acces token with the help of the refresh token without authenticating..
    $cookie = $this->Cookie->read('token');

    if(!empty($cookie)){
        $client->refreshToken($this->Cookie->read('token'));
    }

And thats it! IF you have any questions, feel free to leave a comment below and I will answer the best I can. Goodluck and Cheers!

hope_industries
  • 463
  • 1
  • 5
  • 12
0

Instead of using cookies and sessions you should save it in the database and use it.

A similar implementation for drupal site is at Google OAuth2 sandbox at http://drupal.org/sandbox/sadashiv/1857254 This module allows you to handle the authentication from admin interface of drupal. You can then use the fetched access token from google and then use the api function of google_oauth2_account_load or google_oauth2_client_get to get the Google_Client and carry your api call.

0

Much the same as hope industries but after testing I only wanted to refresh the token when I had to. Full source just change the keys etc at the top:

require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_CalendarService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Calendar PHP Starter Application");
// Visit https://code.google.com/apis/console?api=calendar to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('your_id');
$client->setClientSecret('your_secret');
$client->setRedirectUri("http://localhost/your_redirect.php");
$client->setDeveloperKey('your_key');

$cal = new Google_CalendarService($client);

if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . $query_string);
}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);//update token
    //json decode the session token and save it in a variable as object
    $sessionToken = json_decode($_SESSION['token']);
    //Save the refresh token (object->refresh_token) into a cookie called 'token' and make last for 1 month
    if (isset($sessionToken->refresh_token)) { //refresh token is only set after a proper authorisation
        $number_of_days = 30 ;
        $date_of_expiry = time() + 60 * 60 * 24 * $number_of_days ;
        setcookie('token', $sessionToken->refresh_token, $date_of_expiry);
    }
}
else if (isset($_COOKIE["token"])) {//if we don't have a session we will grab it from the cookie
    $client->refreshToken($_COOKIE["token"]);//update token
}

if ($client->getAccessToken()) {
    $calList = $cal->calendarList->listCalendarList();
    print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
    $_SESSION['token'] = $client->getAccessToken();
} else {
    $authUrl = $client->createAuthUrl();
    print "<a class='login' href='$authUrl'>Select a calendar!</a>";
}
Soth
  • 2,901
  • 2
  • 27
  • 27