7
votes

Seems that the latest version of the google-api-php-client for PHP doesn't line up with the docs @ https://developers.google.com/drive/web/examples/php

Looking at the src code I'm seeing that it's looking for keys in the downloaded JSON that the setAuthConfigFile() method can't find: client_secret, installed, web, redirect_uris (others?) are not present in the downloaded JSON. Only private_key_id, private_key, client_email, client_id, and type are present.

The code and docs seem really disorganized and out of sync... wouldn't be the first for Google. Has anyone gotten OAuth working recently using that library?

4
Any updates on this? Having the same issue here.Nebez Briefkani
@NebezBriefkani I had the same problem. In my case, the client_secret.json file was by default set with read only on mac. I did chmod 777(gave write permissions) to this file, which fixed the issue.Mr_Green

4 Answers

7
votes

There is a difference between a "service account" and a "web apllication" to make calls to the API. When you created a "service account" you will get the file described above, a JSON file with private_key, client_email, client_id etc.

When you create a web application you will be given a client_id, client_secret, redirect_uri etc.

I would suggest reading these pages to choose which key and login you need (on both pages you find examples to integrate it in PHP):

You can use the Google APIs Client Library for PHP to create web server applications that use OAuth 2.0 authorization to access Google APIs. OAuth 2.0 allows users to share specific data with an application while keeping their usernames, passwords, and other information private. For example, a web application can use OAuth 2.0 to obtain permission from users to store files in their Google Drives.

https://developers.google.com/api-client-library/php/auth/web-app

Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data. For example, an application that uses Google Cloud Datastore for data persistence would use a service account to authenticate its calls to the Google Cloud Datastore API.

https://developers.google.com/api-client-library/php/auth/service-accounts

2
votes

There's a new function in the php library that gets close to this, but doesn't allow setting sub, so always gives authorization fails. So, first update the php library function loadServiceAccountJson in src/Google/Client.php to this:

  public function loadServiceAccountJson($jsonLocation, $scopes)
  {
    $data = json_decode(file_get_contents($jsonLocation));
    if (isset($data->type) && $data->type == 'service_account') {
      // Service Account format.
      $cred = new Google_Auth_AssertionCredentials(
          $data->client_email,
          $scopes,
          $data->private_key,
          'notasecret',
          'http://oauth.net/grant_type/jwt/1.0/bearer',
          $data->sub
      );
      return $cred;
    } else {
      throw new Google_Exception("Invalid service account JSON file.");
    }
  }

Then, add a value sub to the data in your server auth json file:

{
  "private_key_id": "removed",
  "private_key": "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----\n",
  "client_email": "removed",
  "client_id": "removed",
  "redirect_uris":[your urls here],
  "type": "service_account",
  "sub": "[email protected]"
}

Now, obtain authorization:

$credentials = $client->loadServiceAccountJson('serverauth.json',"https://www.googleapis.com/auth/admin.directory.user.readonly");
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion();
}

Where serverauth.json is the JSON keyfile downloaded from the service account you want to use, and added the sub line to.

And lastly, create a Directory instance and query it:

$service = new Google_Service_Directory($client);
$optParams = array(
        'domain' => 'google.domain.com',
        'orderBy' => 'email',
        'viewType' => 'domain_public',
        'query' => "givenName:'Joe' familyName:'Schmoe Jr'"
);
$results = $service->users->listUsers($optParams);
$users = $results->getUsers();

print_r($users);
0
votes

I understand your risk, You have a problem with Google API. In Google API console there are 3 kinds of json File, one is Web , second is Service and the last is Installed. the choice you many need to use is that Installed because You will get Key, Installed or other..

0
votes

1) "CREDENTIALS_PATH" should point to a nonexistent file (in a writeble path)

2) "CLIENT_SECRET_PATH" should point to the "ID client OAuth 2.0" credential file, created and downloaded from the Google Console in the Api Credential section.

For a server side php script, like yours, pay attention when creating the "ID client OAuth 2.0" record: on the creation wizard, you should select "other" type of application and not the "web" type.

Regards