Search code examples
phpoauth-2.0google-api-php-clientgoogle-admin-sdkserver-to-server

Trouble making authenticated calls to Google API via OAuth


When I try to make a call to the Google Directory API using Server to Server authentication, I get the error message "Not Authorized to access this resource/api".

What I did:

  1. Created an App in the Google Developers Console.
  2. Downloaded the private key and looked up the service account name.
  3. Activated the Admin SDK under APIs.
  4. Downloaded the google-api-php-client.
  5. Wrote the following code:

$serviceAccountName = '[email protected]';
$scopes = 'https://www.googleapis.com/auth/admin.directory.group';
$privateKeyFile = dirname(__FILE__).'/../certs/googleapi-privatekey.p12';

$client = new Google_Client();
$client->setApplicationName('API Project');
$client->setScopes($scopes);
$cred = new Google_Auth_AssertionCredentials($serviceAccountName, $scopes, file_get_contents($privateKeyFile));
$client->setAssertionCredentials($cred);
$client->getAuth()->refreshTokenWithAssertion();

$req = new Google_Http_Request("https://www.googleapis.com/admin/directory/v1/groups/[email protected]/members?maxResults=1000");

$val = $client->getAuth()->authenticatedRequest($req);

var_dump($client->getAuth()->getAccessToken());
var_dump($val->getResponseBody());
  1. Executing that small script yields a valid access token, valid for an hour and the following error message:

{ "error": { "errors": [ { "domain": "global", "reason": "forbidden", "message": "Not Authorized to access this resource/api" } ], "code": 403, "message": "Not Authorized to access this resource/api" } }

I get the same error when I try to do the same request on the Google OAuth playground with the access key from my PHP script. Do I have to activate access to the group data for that service account somewhere in the Developers Console?


Solution

  • Beyond granting the service account client id access to the given scopes in your Google Apps Control Panel, you need to tell the service account to impersonate a super administrator user within your Google Apps domain:

    $auth->sub = $adminEmail;
    

    For some reason, the Admin SDK docs don't contain a PHP sample but there's sample code for instantiating a service account in the Google Drive docs.