Google OAuth 2.0 with Service account with PHP: "Invalid token format error"

Le Caboom picture Le Caboom · Sep 30, 2016 · Viewed 7.4k times · Source

I have created my service account, got the private_key and delegated domain wide authority.

Here is my code trying to authenticate with the service account but getting the same "Invalid token format error":

session_start();
include_once 'google-api-php/vendor/autoload.php';

function getClient() {
$client = new Google_Client();
$client->setApplicationName('theName');
$client->setScopes('https://www.googleapis.com/auth/admin.directory.user.readonly');
$client->setAccessType('offline');
$client->setSubject('[email protected]');
$client->setAuthConfig('private_key.json');

// Load previously authorized credentials from a file.
$credentialsPath = 'private_key.json';
if (file_exists($credentialsPath)) {
    $accessToken = json_decode(file_get_contents($credentialsPath), true);
}
else {
    // Request authorization from the user.
    $authUrl = $client->createAuthUrl();
    printf("Open the following link in your browser:\n%s\n", $authUrl);
    print 'Enter verification code: ';
    $authCode = trim(fgets(STDIN));

    // Exchange authorization code for an access token.
    $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, json_encode($accessToken));
    printf("Credentials saved to %s\n", $credentialsPath);
}

$client->setAccessToken($accessToken);

// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}

And here is screenshot of what I get from $accessToken just before

$client->setAccessToken($accessToken);

with the error itself:

https://postimg.org/image/ajgan5y27/

Any help will be appreciated. Thanks!

Answer

Le Caboom picture Le Caboom · Sep 30, 2016

The problem was the outdated google api documentation. Turns out the new version for the "getClient" function needs only this to work in case anyone is having troubles:

function getClient() {
    $client = new Google_Client();
    $client->setAuthConfig('private_key.json');
    $client->setApplicationName('theName');
    $client->setScopes(Google_Service_Sheets::SPREADSHEETS_READONLY);
    return $client;
}

Doesn't need to $client->setAccessToken(); at all...

Good job google... Those are the outdated and unreliable documentation pages I took this code from:

https://developers.google.com/admin-sdk/directory/v1/quickstart/php and https://developers.google.com/api-client-library/php/auth/service-accounts

One more thing: in case you need to play with Google Sheets, you may need to add the account service ID ([email protected]) to the google sheet document you want to extract information from.