Trouble making authenticated calls to Google API v

2019-03-01 22:24发布

问题:

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 = 'XXXXXXXXXXX@developer.gserviceaccount.com';
$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/group-id@example.com/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?

回答1:

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.



回答2:

I found by trial and error that removing "admin." from the scopes makes it work (in addition to everything said above about following these steps: https://developers.google.com/drive/web/delegation#delegate_domain-wide_authority_to_your_service_account ).

$cs = json_decode(file_get_contents(<MY SECRET PATH> . 'client_secrets.json'), true); 
$cs = $cs['web'];
$cred = new Google_Auth_AssertionCredentials(
    $cs['client_email'], //why do they call this "service account name" ? Misleading >:(
    array(
        'https://www.googleapis.com/auth/directory.user',
        'https://www.googleapis.com/auth/directory.group',
        'https://www.googleapis.com/auth/directory.group.member'
    ),
    $key,
    'notasecret',
    'http://oauth.net/grant_type/jwt/1.0/bearer',
    '<MY EMAIL IN THE DOMAIN>' //_my_ email as an user with admin rights
);