2

This is my serivice.php file :

putenv('GOOGLE_APPLICATION_CREDENTIALS=service-account.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();

$client->setSubject('user@mydomain.com');

$client->setScopes('https://www.googleapis.com/auth/drive.file');

$service = new Google_Service_Drive($client);
//Create a new drive file
$file = new Google_Service_Drive_DriveFile();

$file->setName('example');
$file->setMimeType('application/vnd.google-apps.file');
$data = file_get_contents('exapmle.txt');
  //Upload the file to google docs
$createdFile = $service->files->create($file, array(
        'data' => $data,
        'mimeType' => $mimeType,
        'uploadType' => 'multipart'
      ));

I have service-account.json file in same working directory.

But i am getting this error :

PHP Fatal error:  Uncaught Google_Service_Exception: {
 "error": "unauthorized_client",
 "error_description": "Client is unauthorized to retrieve access tokens using this method."
}
 in \vendor\google\apiclient\src\Google\Http\REST.php:118

I have Enabled G Suite Domain-wide Delegation also.

Aneeb Ryan
  • 107
  • 5
  • this kind of error happens when the account is not configured properly...maybe [this issue](https://github.com/google/google-api-php-client/issues/801#issuecomment-171417538) could help you to figure out what you've missed. – Elmer Dantas May 15 '17 at 09:46
  • Make sure that you have setup the domain delegation https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority Your service account needs access to user@mydomain.com files. – Linda Lawton - DaImTo May 15 '17 at 09:57
  • Hi @DaImTo , I have setup the domain delegation. I also mentioned in the last line of my question. – Aneeb Ryan May 15 '17 at 11:37
  • Hi @ElmerDantas, I have configured the account using the link [link](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority ) I can read the emails of my user successfully but cannot upload the file. – Aneeb Ryan May 15 '17 at 11:45
  • I have also added the scope for drive "https://www.googleapis.com/auth/drive " here in MANAGE API ACCESS (https://admin.google.com/AdminHome?chromeless=1#OGX:ManageOauthClients) – Aneeb Ryan May 15 '17 at 13:42
  • I've never used service account, so I don't know all configuration you need to set...as I said, you're probably missing something. Try to read this other question http://stackoverflow.com/questions/25707891/google-drive-php-api-simple-file-upload (has more data configuration than your solution) – Elmer Dantas May 15 '17 at 14:20
  • @ElmerDantas , i read the link you suggested but that is the simple file upload using the access token. – Aneeb Ryan May 15 '17 at 14:38
  • $client->setSubject('user@mydomain.com'); If i donot add this line i can easily read the files of my own drive (My account through which this file is create "service-account.json" ) But i need to access the files of my domain users. – Aneeb Ryan May 15 '17 at 14:39
  • 1
    I see three issues with your code: - The authorisation error indicates that DwD isn't configured, or you're using the wrong scope. The scope in your code must be the exactly the same as that under Security > Advanced > Manage API client access. - Your code uses an undefined $mimeType variable, in the metadata array. If you want to use the $mimeType variable in the array, ensure that it is defined in advance. - It appears as though the file name is misspelled, 'exapmle.txt' instead of 'example.txt'. Ensure that the path to the file is correct, and that the specified file actually exists. – Fergal May 15 '17 at 16:21
  • Hi @Fergal, Thank you for the suggestions but that is just the sample code the misspelled or mimetype was not the actual issue. The issue was the scope. In manage Api access i added the scope: "https://www.googleapis.com/auth/drive" But here in the code i was adding : "https://www.googleapis.com/auth/drive.file" So by your suggestion i changed to scope to this "https://www.googleapis.com/auth/drive" and the issue was fixed. – Aneeb Ryan May 16 '17 at 05:48
  • as I said...it was configuration error. When it comes to API's you need to pay attention in each step of configuration. Good that you figured out. – Elmer Dantas May 16 '17 at 07:06

1 Answers1

1

To put my note in full context:

In the code the Drive.file scope was defined:

$client->setScopes('https://www.googleapis.com/auth/drive.file');

but in the Admin console under Security > Advanced > Manage API client access, the scopes list authorised the following for domain wide delegation.

https://googleapis.com/auth/drive

As indicated at https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority,

  1. In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.

As the scopes requested didn't match a scope in the list of scopes authorised for the client ID, authorisation was refused, and a 403 error was served.

Fergal
  • 126
  • 2
  • 6
  • I have the same problem and my scopes match (https://www.googleapis.com/auth/calendar). Is there something else that can affect this? – Eye Patch Dec 12 '22 at 22:08
  • Hi Eye Patch, as noted at https://developers.google.com/calendar/api/v3/reference/calendars/get#auth, the scope added in the admin console, and requested by your application must be one of https://www.googleapis.com/auth/calendar.readonly, or https://www.googleapis.com/auth/calendar. If you specified googleapis.com/auth/calendar for either, it's not a valid scope, so the authorisation request will fail. – Fergal Jan 15 '23 at 03:31