Google Drive API PHP - unauthorized_client - php

I have problem using Service Account to authenticate:
putenv('GOOGLE_APPLICATION_CREDENTIALS='/path/to/google.json');
$client = new \Google_Client();
$client->addScope(\Google_Service_Drive::DRIVE);
$client->useApplicationDefaultCredentials();
$client->setAccessType('offline');
$client->setSubject('xxx#xxx.com');
But it display error like this:
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method."
}
When I removed
$client->setSubject('xxx#xxx.com');
It works(I have access), but there is other problem, I can't see any files created through application in my google drive(using UI). From what I heard it's just because I use Service Account and it's creating files on his own space where I can have access only through API. I need to have access to files from API and from google drive application too.
Also I need to have access to my google drive without login to my google account(without redirecting user to google login page).
If you could help me with this problem and show some examples I would be very thankful.

You need to remember that a service account is not you. A service account is a dummy user it has its own google drive account. There will be no files on the service acccounts google drive account until you upload them.
There is no web view for a service account.
You can share a folder on your personal google drive account with the service account like you would any other user using the email address. Just make sure to have the serivce account update the permissions or you will have files on your drive account you dont have access to.
the service account can create a folder on its google drive account and share it with you. You should then be able to see it in the web view of your google drive account.
Storage limit of a service account is linked to the owner of the service account not the account it is uploading to.

Service accounts is used to act on behalf a user. You can set the user to be your account. This way, the service account is acting on your behalf and you can see everything (using the UI) got created via you app.
To avoid the error you are facing, ensure that the following is done:
Create Service account using the instructions in the link below. Please note that step number 6 is an important step and don't ignore it. https://support.google.com/a/answer/7378726?hl=en
Once a service account is created, you need to grant that account permissions using G-suite.
Copy the client_id. You can find it in the json file (service account credential file) or Using the Api Console, by going to Credentials > Manage Service Account then 'View Client ID'. Copy the client_id to clipboard
Launch the G-Suite Admin Console
Go to Security>Advanced Settings>Mange API client access.
Paste the client_id in the Client Name field, add the following API scopes and click Authorize:
https://www.googleapis.com/auth/admin.directory.group,
https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/calendar.readonly,
https://www.googleapis.com/auth/drive
Note: If step 3 is not done, you will get the error you are getting
References:
https://support.google.com/a/answer/7378726?hl=en
https://github.com/sazaamout/gDrive

Related

Correct OAuth2.0 setup for Service Account to use Google Ads Api?

I have created my service account, following the Google documentation as best I can. I created a JSON Key File and have used it successfully to create and refresh my access token, but when I try to call the Google Ads API using that access token I get a 401 with the message "User in the cookie is not a valid Ads user."
I am using a PHP cURL request, not the Google Client library.
My suspicion is that I have something set up incorrectly somewhere between the Master Ad account, the service account and the project in the Google Cloud Console, but I am finding the documentation confusing and unhelpful.
I submitted a question to the Google Ads API google group, and the support person said that my setup looked OK, but also admitted that he cannot see all of it from his end.
I have created the following pieces of the puzzle:
Google Ads Master Account
Developer Token
Project in Google Cloud Console
Service Account in Project
Private Key for Service Account
Set email of Master Ads Account to role of Owner of Service Account
Enabled Domain-Wide Delegation for the Service Account with scope "https://www.googleapis.com/auth/adwords"
Requested and received Access Token with the private key in the JSON file
Please let me know what extra details I should provide to get my issue resolved. Thanks in advance.
My error was that when I created my Access Token, I passed the Gmail account that owns the Google Ads Manager Account to the parameter $sub, but to access Google Ads API the Service Account must impersonate a user in the domain that is registered with the Google Workspace. This point is made in the documentation, but is rather understated.
To fix the issue I granted access to the Google Ads Manager Account to an email account in the Workspace domain, and passed that email address to $sub; now I have made a successful test call to the Google Ads API.
I attach an anonymized summary of my configuration in case it helps anyone who might be reading this in the future.

Issue fetching data from google analytics api

I've been following Hello Analytics Reporting API v4; PHP quickstart for service accounts in order to complete the set up for an API that will get data from a Google Analytics Report.
I've completed the first three steps as I created the service account, downloaded the private key, and installed the client library. I put the private key JSON file in the same directory as the HelloAnalytics.php sample file I got from the site. I used the view_id that is found in the view settings for the analytics campaign. I then changed the $KEY_FILE_LOCATION to the name of the private key file.
For some reason, when I run sample analytics file, I get the a 403 error saying that permission has been denied even though I have added permission for the API inside of the campaign admin.
Did I skip a step? What could be going wrong?
Yes you have missed a step. Service accounts must be preauthorized.
Add service account to the Google Analytics account
The newly created service account will have an email address that looks similar to:
quickstart#PROJECT-ID.iam.gserviceaccount.com
Use this email address to add a user to the Google analytics view you want to access via the API. For this tutorial only Read & Analyze permissions are needed.
Go to the Google analytics website in the admin section and add the service account email address as a user. At the ACCOUNT level.

Google MC Funnels - Service account credentials?

There are two different types keys for " Service account credentials " JSON and P12
Please, which one is indicated to work with "Google MC Funnels API"?
Either can be used with MFC API. Service account credentials and Oauth2 credentials have nothing to do with the which API you can access. Except with regard to some APIs which don't support service accounts (YouTube API , and blogger to name two). Service account and Oauth2 are all about gaining access to the data you need.
Service account p12 file
Service accounts are used to access data you the developer have access to. If you want to grant someone else access to see your Google Analyitcs data you would use a service account. Setup will require that you take the service account email address and add it as a user at the account level in the google analytics website admin section. it must be the account level.
Oauth authentication Json file
Oauth2 will request a user give your application permission to access their data.

User does not have any Google Analytics account

My boss registered an Google Analytics account and shared his website Analytics account with me.
Now I have the authority to see all data about the website. I want to use the Google Analytics API to request data from Google Analytics with my php script.
Authorization is done without any problems, until the script tries to access data. The return code is 403, and error message is :
User does not have any Google Analytics account。
This will depend on what method of authentication you are using.
Oauth2:
When your PHP script pops up and asks a user to authenticate the Google account the user users to authenticate must have access to a Google analytics account. In this case it doesn't. Note: the user is only going to be able to see there own Google Analytics data not date for your website unless your boss goes and grants them access as well.
service account:
In the event you are using a service account to authenticate. The service account by default doesn't have access to any Google Analytics accounts you need to grant it access just like your boss granted you access. Take the service account email address from Google Developer console and add it at the ACCOUNT level it must be the ACCOUNT level to the Google Analytics website. then the service account will have access to the data for that account.

How to access Google Spreadsheets with a service account credentials?

I have created a server side application in PHP that's supposed to work with Google Spreadsheets.
I'm able to authenticate successfully with OAuth 2.0 authentication, but when requesting the list of the spreadsheets from Google, I only get the spreadsheets shared with the service account by the spreadsheet owner.
Is there a way that service account could retrieve all the spreadsheets owned by my main account not the service one, including those not explicitly shared with the service account?
Also I still want to keep the spreadsheets private so noone can access them without my permission, but I need the service account to have full access to both existing and new spreadsheets.
Any advice is appreciated.
Here is a sample script that uses a service account to read the contents of a Google Spreadsheet's sheet. Have a look at the README for instructions to set it up:
https://github.com/juampynr/google-spreadsheet-reader
You have to change approach:
Create a service account in Drive. You can manage and use this account only with the API (not with the web interface as usually)
With the Drive API you can list, create, update, delete and change the permissions of the files. When you create a new file, you can share it - always with API - to the users you want, make the new file public or change the ownership.
Please take a look: https://developers.google.com/drive/v2/reference/permissions
I am assuming you use Google Apps and not a personal GMail account. You can use your service account to impersonate your main account.
Note that here I am talking of a service account in the way Google means it : a private key (in p12 format) and an identifier. This is not a Google Apps account used for technical purposes. More information here.
This is done by :
Authorizing your service account on your Google Apps domain
Modify the code you use to generate the API credentials
The steps are exactly the same for the Spreadsheet API and for the Drive API.
To first authorize your service account to impersonate the domain users, you can follow this documentation. Here are the basic steps. You must be a domain super administrator to perform this task.
Go to your Google Apps domain’s Admin console : https://admin.google.com
Select Security from the list of controls. If you don't see Security listed, select More
controls from the gray bar at the bottom of the page, then select
Security from the list of controls.
Select Advanced settings from
the list of options.
Select Manage third party OAuth Client access
in the Authentication section.
In the Client name field enter the
service account's Client ID. In the One or More API Scopes field
enter the list of scopes that your application should be granted
access to. In your case that would be at least the Spreadsheet API scope : https://spreadsheets.google.com/feeds
When this is done, you need to update your code so that it impersonates your main account :
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
'YOUR_SERVICE_ACCOUNT_EMAIL',
array('https://spreadsheets.google.com/feeds'),
$key);
$auth->sub = 'yourmainaccount#domain.com';
You can then use the $authvariable to generate the OAuth tokens you need to access the spreadsheet API. I am not sure which client you use for this so the way you inject the access token will depend on which client you use.
Also, note that this token will expire after 1 hour, and then the API will start returning Session Expired errors. If your client does not handle this automatically, you will need to catch the error and regenerate the token.

Categories