How to access Google Spreadsheets with a service account credentials? - php

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.

Related

Can not access the Adsense Management API

Can not access the AdSense API no matter what I try. I have tried both service account and OAuth authentications.
What I am trying to accomplish:
Creating a bot that will grab the Adsense revenue earned and store it in an in-house database for tracking revenue over time. I do not want to have authentication issues, I want a server-to-server configuration.
What I do know is you can have access tokens and refresh tokens under OAuth. I've yet to be able to make them work under any available APIs with Adsense. Note: I have built an API to work with AdWords no problem.
Errors: (Between the types of authentication, I can not pass these)
"Account Not Found"
"Client is unauthorized to retrieve access tokens using this method."
What I have done so far:
The Adsense Management API is enabled.
Credentials Created: Service Account
Credentials Created: oAuth 2.0 Client ID
The GSuite account has access to APIs (includes "enabled api access" and "managed API client access")
Libraries (trying) to use:
https://developers.google.com/api-client-library/php/
https://github.com/google/google-api-php-client
https://github.com/google/google-api-php-client-services
(outdated) https://github.com/googleads/googleads-adsense-examples
Example code: (using the service account)
$client = new \Google_Client();
$client->setAuthConfig(WRITEPATH . 'auth/adsense-client.json');
$client->setIncludeGrantedScopes(true);
$client->addScope('https://www.googleapis.com/auth/adsense');
$client->setSubject('email#example.com');
// trying to fire the services
$service = new \Google_Service_AdSense($client);
$report = $service->accounts_reports->generate('clientId', $startDate, $endDate, $optParams);
This script fires the "Client is unauthorized to retrieve access tokens using this method." error message. However, the email address being used is able to access the adsense account, the APIs are enabled and configured on the admin domain level.
Is there an easier way? is there anyone who can lead me in the right direction?
Service account
I am not all that sure that Service accounts work with adsence. You can try by going to the adsence website and under manageUsers add the service account email address. The issue here is its going to sit there at pending i think because the service account needs to confirm that it has been added. There is no way to do that.
Admin domain level
If you are trying to add domain wide delegation to this i wouldn't bother with that either as far as i can see its not supported either.
Client is unauthorized to retrieve access tokens using this method.
As for that error i may be able to help. It means that you have taken the credentials file you downloaded for a service account and are trying to use it with the code for Oauth2. or visa versa. Download the credentials file again and try again.
I have some sample code that may help here

Google Drive API PHP - unauthorized_client

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

PHP Google_Client insert youtube playlistItem (2-leg-oauth)

My web using the PHP Google_Client to insert the youtube playlistItem in my playlist (2-leg-oauth),
and get the error
Client is unauthorized to retrieve access tokens using this method.
Where can I setting the server using my-account#gmail.com to have the same permission to access google api
such like insert playlistItem,
or is there having another way without using my-account#gmail.com to get same permission?
PHP Code:
putenv('GOOGLE_APPLICATION_CREDENTIALS=client_secret.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/youtube');
$client->setSubject('my-account#gmail.com');
If you have delegated domain-wide access to the service account and
you want to impersonate a user account, specify the email address of
the user account use
$client->setSubject($user_to_impersonate);
The YouTube API doesn't support delegated domain-wide access or service accounts. You will need to authenticate with Oauth2.
see PHP Code Samples
You're hitting a common problem. Many developers think that a Service Account is the correct way for server apps to communicate to Google's API services for a given Google account. It isn't! A Service Account, as its name implies, is a brand new account (actually a kind of half-account since you can't actually log in to it) that is dedicated to your app.
What you need to do is a one-time procedure to generate a Refresh Token, which you will store securely. Thereafter, whenever you need to access a Google API such as YouTube, you will use that Refresh Token to generate an Access Token, which you will include in each API request. The steps are enumerated How do I authorise an app (web or installed) without user intervention? (canonical ?) and https://www.youtube.com/watch?v=hfWe1gPCnzc

How to revoke access to Microsoft APP for a user in php

I've searched long and hard about how to revoke access to the Microsoft APP for a user account in PHP or any programming languages for that matter but couldn't find it...
There doesn't seem to be any msdn docs for achieving it... nor any API URL Endpoints in "login.microsoftonline.com".
Should we just remove the token in our web app database and just leave it?
but while accessing the account settings -> security and privacy -> connected apps the app is still there...
Plzzz someone share the url endpoint or the right method to do so
note:
but google php client has the revoke method and they send the token to endpoint "https://accounts.google.com/o/oauth2/revoke"
is there any similar revoke endpoint for microsoft?
If you are looking for the method to disable the user account in your tenant to access against to your AD applications.
You can set the accountEnabled property in the user account profile to false, which will lock the user account to prevent it authorize or authentic your applications.
You can leverage Microsoft Graph APIs to handle these operations. Refer to https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/user_update for the details of this API in Microsoft Graph.
And here is the sample in PHP at https://github.com/Azure-Samples/active-directory-php-graphapi-web, which presents how to use Microsoft Graph to handle users accounts in tenant.

Google Apps SSO + Get Users in Google Apps Domain

I have recently implemented the SSO functionality for a Google Apps Marketplace app we are developing. In simple words: it provides a way to retrieve the Google Apps' user's email and log him in in your website, without the need of authorization on his end. You just need the consumer key and consumer secret, provided by Google to the app during installation on your domain (the installing user also authorizes (a one time action) any other permissions you request in the Manifest file).
Now I have somehow managed to get the SSO user login working using JanRain's OpenID PHP library and adding Google Apps as provider using the PHP Extensions for Google Apps OpenID Discovery.
However, after logging in, I need to implement a functionality that will retrieve all users in a given Google Apps domain. I've already did that using oAuth2 authentication and the following Directory API. However, this requires the existense of a consumer key, consumer secret and a redirect URL (that must be registered in the Google API console).
Is there a way to remove this convenience and instead allow our users to directly be able to get their Google Apps domain's users, using the existing SSO authentication we made in the background while logging him in? Otherwise, it will be too much hassle for the user to register the app at the Google API console, enter the correct redirect URL and set it up in our website and then he will be able to get his domain's users.
Regular users cannot use the Directory API, you'll need to authenticate as an admin user to make Directory API calls.
Depending on your needs though for accessing all users, you may be able to get by with requesting access to the user's Contacts scope and grabbing a copy of the full Global Address List which contains information on all non-hidden domain users as well as non-hidden groups and shared contacts.

Categories