Connecting to the Google Sites API as a "Service Account" - php

I am trying to read a feed from a Google Sites account (Google apps).
I don't need my app to require every user to login so i created my ClientID as a "Service Account" in the "Google API console".
I have added this Client ID and the scope (https://sites.google.com/feeds/) to the "Mange API client access" page in my google apps control panel.
I connect using the code below, all constants are defined in my code with the right values.
// api dependencies
require_once(GOOGLE_API_PATH);
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName(GOOGLE_API_NAME);
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
GOOGLE_API_EMAIL,
array(GOOGLE_API_SCOPE),
file_get_contents(GOOGLE_API_PK)
));
$client->setClientId(GOOGLE_API_CLIENTID);
// create service
$req = new Google_HttpRequest("https://sites.google.com/feeds/content/<herismydomainname.com>/intranet");
$val = $client->getIo()->authenticatedRequest($req);
// The contacts api only returns XML responses.
$response = json_encode($val->getResponseBody());
print "<pre>" . print_r(json_decode($response, true), true) . "</pre>";
The response i get is "Not authorized to access this feed "
When i try to get this feed in the OAuth2.0 playground logging in using my google apps account i get the expected response.
What am i overlooking here?

Service accounts and Google Sites can't be used together currently. Google Apps provides a consumer secret that can be used to access data across your domain as Two-Legged OAuth within OAuth 1.0a.
Check out http://support.google.com/a/bin/answer.py?hl=en&answer=162105 for how to configure your Apps account, and the sample code at https://developers.google.com/gdata/docs/auth/oauth#2LeggedOAuth.

Related

How to get Business Locations (and Reviews) via Service Account authentication

I can't get the Locations list from my business under my code (PHP using the "Google APIs Client Library for PHP" together with "Google_Service_MyBusiness" Classes) when I use the "Service Account" authentication, the API returns an empty Location List.
I already have the Prerequisites and did the Basic setup, by the way, I got the information with success on OAuth Playground, under a specific AccountId, Eg: 1111111111, provided by another response there on the "OAuth Playground".
(PS: I tested with my "PERSONAL" and "LOCATION_GROUP" accounts and got success with both).
But when I try to do it over my code via Server Account authentication, I can't get all the information, just the Account data that return another AccoundId, Eg: 2222222222, different of the Accounts that I got on OAuth Playground.
I did the Authentication process on OAuth Playground, using the same project where I created the "Service Account", by the way, the Permission of this "Service Account" is OWNER.
Previously, my role in my company on the Google My Business was "SITE_MANAGER", so I saw a forum answer where just "MANAGER" level/role can list the Locations, so I requested to change my permission, but continues as not the success on Locations listing.
So, I saw another Google My Business support article recommending create a "Location Group" and put my current "Location" into this group to make easy handle it, I did it and no success again.
My code is simple, based on Google guide, OAuth 2.0 for Server to Server Applications, and some Forum Questions (BTW the author's question have the same issue than me):
<?php
putenv('GOOGLE_APPLICATION_CREDENTIALS=service-account-credentials.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope("https://www.googleapis.com/auth/plus.business.manage");
require_once('Google_Service_MyBusiness.php');
$mybusinessService = new Google_Service_MyBusiness($client);
$accounts = $mybusinessService->accounts;
$accountsList = $accounts->listAccounts()->getAccounts();
foreach ($accountsList as $accKey => $account) {
var_dump('$account->name', $account->name);
$locations = $mybusinessService->accounts_locations;
$locationsList = $locations->listAccountsLocations($account->name)->getLocations();
var_dump('$locationsList', $locationsList);
// Final Goal of my Code
if (empty($locationsList)===false) {
foreach ($locationsList as $locKey => $location) {
$reviews = $mybusinessService->accounts_locations_reviews;
$listReviewsResponse = $reviews->listAccountsLocationsReviews($location->name);
$reviewsList = $listReviewsResponse->getReviews();
var_dump('$reviewsList', $reviewsList);
}
}
}
I expected the Location of my business (also the reviews, but it a next step), but I just got the empty Location list.
Finally, I got success using the ClientId/ClientSecret keys together with Refresh Token previously received on Google OAuth 2 Playground on the first time that I give permission to (my) App, instead "Service Account" authentication way :)
$client = new Google_Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->addScope("https://www.googleapis.com/auth/plus.business.manage");
$client->setSubject('my email user on GMB');
$client->refreshToken(' ###### ')
Now I got all the needed data for my application.

Cannot connect with a Google Service Account via php and google apiclient alpha 2.0.0

I'm having a problem connecting through the google apiclient 2.0.0 as installed via composer.
Here's what I've done so far:
I installed apiclient via composer.
I went to https://console.cloud.google.com/apis/credentials?my-project and navigated to the API manager > Credentials page.
I created credentials for a Service Account and downloaded the json. I then uploaded the json to my server.
I enabled Domain Wide Delegation for the account by managing my service accounts.
I verified my domain name under the 'Domain Verification' tab.
Next I navigated to my calendar and shared the calendar with the email address associated with my service account, granting manage access.
Then I shared my calendar with the email address of the service account.
Now I'm trying to use the api to connect and running into authorization problems.
$json_file = '/path/to/service-account-credentials.json';
$scopes = [
Google_Service_Calendar::CALENDAR,
Google_Service_Calendar::CALENDAR_READONLY
];
// create a new client and authorize
$client = new Google_Client();
// set the basic information of the client
$client->setApplicationName("Apointments");
$client->setSubject( email-address-to-masquerade-as#mycompany.com );
$client->setAccessType('offline');
// load the json credential file
$client->setAuthConfig( $json_file );
$client->setScopes( $scopes );
// check to see if the token is stored in the session
if( isset( $_SESSION['service_token'] ) )
{
// token was stored, use it with the cilent
$client->setAccessToken( $_SESSION['service_token'] );
}
// test the authorization to see if it is expired
if( $client->isAccessTokenExpired() )
{
// Failed authorization, get a new token
$client->refreshTokenWithAssertion();
}
// store the token in the session
$_SESSION['service_token'] = $client->getAccessToken();
From a stacktrace, I've identified the offending line of code to be:
$client->refreshTokenWithAssertion();
Which yields an error message:
Client error response [url] https://www.googleapis.com/oauth2/v4/token [status code] 401 [reason phrase] Unauthorized
Any thoughts as to where I've gone awry?
Thanks in advance,
Adam
The way you are using Service account is only valid to access data related to your application or to your service account itself. Since you wish to access Google Calendar data, you must be a Google Apps domain administrator with privileges to access any of your domain user's data. Google Calendar data belong to users so you need to specify which user you are trying to access.
You need to authenticate the user, need to get an access token and pass that. If you are getting an access token, you can call token info passing access token to get more information about who the user is associated with it.
Here's a Quick start demo app, use this as your reference: https://developers.google.com/+/web/samples/php

Get user login access token to use youtube API

I am using youtube API for scheduling live events for user in my application.
Once the user logged in my application i need to logged in the same user to our business google account(One google account for all user) without giving login credentials. and to get access token for scheduling the live events.
Is it possible to login the user into google account without giving login credentials(User will not feel he is login to another account).
Is it feasible with PHP?.Please give one example to get access token for youtube API access.
I used the following code for getting access token but service account can't access the youtube service.
My code for getting access token using service account:
<?php
require_once 'Google/autoload.php';
session_start();
$client_id = '395540674667-p64tdfqdsfsdfdsf#dsfd.com';
$Email_address = '54564-drgfdg1#developer.gserviceaccount.com';
$key_file_location = 'Youtube API-5czxczxc86.p12';
$client = new Google_Client();
$client->setApplicationName("Youtube API");
$key = file_get_contents($key_file_location);
// seproate additional scopes with a comma
$scopes = array('https://www.googleapis.com/auth/sqlservice.admin','https://www.googleapis.com/auth/plus.login','https://www.googleapis.com/auth/youtube');
$cred = new Google_Auth_AssertionCredentials($Email_address,
$scopes,
$key);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
//print_r($client);
echo $client->getAccessToken();
?>
I am expecting the answer is something like this.Any one please help
you example about Youtube api, first:
select credentials to your api project from here:
https://console.cloud.google.com/home/dashboard?project= with your project
also you need to have the api enable because google told us "Some APIs are enabled automatically."
when you select:
https://console.cloud.google.com/apis/api/youtube/ with Go to Credentials you have some option into modal window this will help
also.
the php code seem to be ok but also I think you will change after you learn more about Credentials settings.

{ "error" : "invalid_grant" } error with Google Directory API PHP Client SDK

So I am trying all day already and I just can't seem to correctly authenticate to the google API. This is what I did to set up a connection so far:
I first created a service account for my application
Then I added that service account in the third party client access settings on the admin page for our Google Apps domain. I added the scopes for users and groups
I generated a new Client ID for web applications
I downloaded the .p12 file, the secret JSON file for my web Client ID and stored them locally
So I think that's all I need to succesfully authenticate.. I then used the following code to set everything up:
$this->client = new Google_Client();
$this->client->setAuthConfigFile(STORAGE_PATH.'client_secrets.json');
$this->client->addScope(static::$scopes);
$cred = new Google_Auth_AssertionCredentials(
static::$service_account_email,
static::$scopes,
file_get_contents(STORAGE_PATH.'TRICS-key.p12'));
$cred->sub = static::$delegated_admin;
$this->client->setAssertionCredentials($cred);
$this->directory_service = new Google_Service_Directory($this->client);
Does someone know if I am forgetting something?
Oops. I was a fool. I accidentally used the email of the Web Client instead of the service account email. :') The rest of the code seems to function as it should.

Google Apps Admin SDK Directory API 403 in PHP

I'm getting
Error calling GET https://www.googleapis.com/admin/directory/v1/users/email#example.com.com: (403) Not Authorized to access this resource/api
when running
$client = new Google_Client();
$client->setClientId(GOOGLEAPPS_CLIENT_ID);
$client->setApplicationName(SITE_NAME);
$key = file_get_contents(APPLICATION_PATH . 'googleapps-privatekey.p12');
$assertion = new Google_AssertionCredentials(
GOOGLEAPPS_EMAIL_ADDRESS, // the service account name
array('https://www.googleapis.com/auth/admin.directory.user'), // see https://developers.google.com/admin-sdk/directory/v1/guides/authorizing
$key);
$client->setAssertionCredentials($assertion);
$service = new Google_DirectoryService($client);
$user = $service->users->get('email#example.com');
I followed the instructions https://developers.google.com/admin-sdk/directory/v1/guides/prerequisites
and ticked Enable API Access. I used the Google APIs console https://code.google.com/apis/console to generate a Service Account key and got that working OK.
https://groups.google.com/forum/#!msg/google-api-php-client/LM-mwmuZe7I/IA_K5v1R1UMJ
I used the Google PHP library and followed the instructions https://code.google.com/p/google-api-php-client/wiki/OAuth2?hl=no#Service_Accounts to try and get service accounts working. Debugging into their code: I'm authorising fine and getting a fresh Access token as expected https://developers.google.com/accounts/docs/OAuth2ServiceAccount.
I can't figure out why I'm getting the "Not Authorized to access this resource/api" message when everything I have read says I've switched it all on OK. Any ideas?
Just got it working. You need to include the user email of the admin so oAuth authorizes you for that user. Try
$assertion = new Google_AssertionCredentials(
GOOGLEAPPS_EMAIL_ADDRESS, // the service account name
array('https://www.googleapis.com/auth/admin.directory.user'), // see https://developers.google.com/admin-sdk/directory/v1/guides/authorizing
$key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
'admin_user#email.com'
);
Also after that you need to authorize the client_id for the scope you are requesting from Admin console->Security->Advanced Settings->Authentication->Manage OAuth Client access
I was having a similar problem. I'm using the .NET libraries. The [DriveService][1] example was missing a parameter when creating the provider: ServiceAccountUser, which appears to have to be the email address of an ADMIN. I missed that it was an admin and was getting:
Not Authorized to access this resource/api [403]
as soon as I switched it to an admin account, it worked. I'm afraid I don't speak PHP but I hope this helps.
If you get an error
Class 'Google_AssertionCredentials' not found
you are using the newer libraries, and Google_AssertionCredentials is now Google_Auth_AssertionCredentials.
See:
https://github.com/google/google-api-php-client/blob/master/src/Google/Auth/AssertionCredentials.php
Did you grant the service account access to the given scopes within your Control Panel? See the instructions in the Drive SDK and substitute in the Admin SDK scopes as needed.

Categories