Google_AuthException - Could not json decode the token issue

2,740 views
Skip to first unread message

Tyler Bell

unread,
Oct 2, 2013, 12:33:26 AM10/2/13
to google-api...@googlegroups.com
Hello Everyone, 

I've searched this Group, plus others, along with other websites and cannot find a solution to this. Error output is below. I definitely know that setAccessToken should NOT be NULL. Any guidance would be great here. the Google Calendar v3 API documentation is not so great...in fact, the samples are for older API versions.

PHP Fatal error:  Uncaught exception 'Google_AuthException' with message 'Could not json decode the token' in google-api-php-client/src/auth/Google_OAuth2.php:162
Stack trace:
#0 google-api-php-client/src/Google_Client.php(170): Google_OAuth2->setAccessToken(NULL)
#1 Cal.php(16): Google_Client->setAccessToken(true)
#2 {main}
  thrown in google-api-php-client/src/auth/Google_OAuth2.php on line 162

Below is the code for my app:

<?php
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();
$service = new Google_CalendarService($client);
if (isset($_REQUEST['logout'])) {
  unset($_SESSION['token']);
}
if (isset($_SESSION['token'])) {
  $client->setAccessToken($_SESSION['token']);
} else {
  $client->setAccessToken($client->authenticate($_GET['code']));
  $_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
  $client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) { 
$event = new Google_Event();
$event->setSummary('Appointment');
$event->setLocation('Somewhere');
$start = new Google_EventDateTime();
$start->setDateTime('2013-10-05T10:00:00.000-07:00');
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime('2013-10-05T10:25:00.000-07:00');
$event->setEnd($end);
$attendee1 = new Google_EventAttendee();
$attendee1->setEmail('m...@email.com');
// ...
$attendees = array($attendee1);
$event->attendees = $attendees;
$createdEvent = $service->events->insert('primary', $event);
echo $createdEvent->getId();
} else {
echo "failed hard";
}
?>

Tyler Bell

unread,
Oct 2, 2013, 12:47:12 AM10/2/13
to google-api...@googlegroups.com
I forgot to mention that ClientID, Key, etc are kept in my google-api-php-client/src/config.php file
$attendee1->setEmail('my@email.com');

Casey Dinsmore

unread,
Oct 2, 2013, 12:00:24 PM10/2/13
to google-api...@googlegroups.com
Hi Tyler, 

You are right, the access token should not be blank. No access token is returned from $client->authenticate() because you are missing the authorization code. You need the user to grant authorization before you can authenticate and receive an access token. 

Review the example and look at lines 37-38. 


In your code you are bailing out if you don't have an access token, but the correct action is to redirect the user to the $client->createAuthUrl() page, which prompts to give your application access to their calendar. Google then posts an authorization code back to the URL you set with $client->setRedirectUri() (presumably the same script in the example) then it runs $client->authenticate() to fetch the access token. 

You can store an access token in a database and use it to establish a connection or refresh a connection if the current token has expired. 

In my application, I wanted my website to post events to my own calendar. I ran the sample by hand and saved the access token to my database, then I wrote a wrapper class to do the heavy lifting. With the initial access token saved, my website can then post to my calendar (and refresh the token) without redirecting back to the createAuthUrl page, but you have to fetch the access token by hand for your first run.

Posting to an end user's calendar will be slightly different because you will almost always redirect them to the createAuthURL() page. I haven't tried this but it should be fairly similar.

In my experience reading the source code and comments of the client-api helped more than the documentation pages.

Finally, here is a method from my wrapper class that I call from nagios to verify that my access token is working properly.


/** 
 * Test Google API connection & retrieve new token, if necessary.
 *
 * @returns boolean Returns true if connection was a success, otherwise false.
 */
public function testAPIConnection() {
$client = new Google_Client();
$client->setApplicationName("My Scheduling API");
$client->setClientId($this->client_id);
$client->setClientSecret($this->client_secret);
$client->setRedirectUri($this->redirect_uri);
$client->setDeveloperKey($this->api_key);
$client->setAccessType('offline');
$client->setAccessToken($this->access_token);

try {
// Attempt to list the available calendars
$cal = new Google_CalendarService($client);
$cal->calendarList->listCalendarList();

// Fetch the access token
$at = $client->getAccessToken();

// If token changed (likely), then store the new values
if ($at != $this->access_token) {
$this->access_token = $client->getAccessToken();
$at = json_decode($this->access_token);
$this->refresh_token = $at->refresh_token;
$this->last_refresh = date("Y-m-d H:i:s");
}

// Google API: Connection verified.
return(true);
} catch (exception $e) {
// Google API Exception: ". $e->getMessage()
return(false);
}
}




Hope that helps!
Casey




Tyler Bell

unread,
Oct 2, 2013, 1:29:22 PM10/2/13
to google-api...@googlegroups.com
Thanks Casey! I just replied to you, but it may have been sent to your inbox instead of posted here. Sorry for any duplicates.

I will try the authorization steps and we'll see what happens. My app is a little different. It's not based on a website or GUI application. Instead, I have my PHP script that checks a database table for new entries that include a users email address and timestamp for when they have to complete a task. My script will then run and put calendar entries up on that users calendar at the specified time. 

This script I have now just uses my personal accounts clientID, api key, etc, but I hope to use a domain key and secret eventually. Would that change the authentication process drastically?

kyawthura maung

unread,
Oct 2, 2013, 2:06:42 PM10/2/13
to google-api...@googlegroups.com

> --
> You received this message because you are subscribed to the Google Groups "google-api-php-client" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to google-api-php-c...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Reply all
Reply to author
Forward
0 new messages