Uncaught exception 'Google_Exception' with message 'Cant add services after having authenticated - php

I am trying to add google spreadsheet using google drive api in php. But I am getting the following error after authentication.
Uncaught exception 'Google_Exception' with message 'Cant add services after having authenticated' in /var/www/html/spreadsheet/google/src/Google_Client.php:119 Stack trace: #0 /var/www/html/spreadsheet/google/src/contrib/Google_DriveService.php(1046): Google_Client->addService('drive', 'v2') #1 /var/www/html/spreadsheet/index.php(20): Google_DriveService->__construct(Object(Google_Client)) #2 {main} thrown in /var/www/html/spreadsheet/google/src/Google_Client.php on line 119
My code:
<?php
require '/var/www/html/spreadsheet/google/src/Google_Client.php';
require '/var/www/html/spreadsheet/google/src/contrib/Google_DriveService.php';
require '/var/www/html/spreadsheet/google/src/contrib/Google_Oauth2Service.php';
$client = new Google_Client();
$client->setClientId('xxxxx-vdbo5lga3sq7g8q4g8adgqh72m0ng8ef.apps.googleusercontent.com');
$client->setClientSecret('BCGuyCPHwNflflBU5jDQ25LQ');
$client->setRedirectUri('http://localhost/spreadsheet/index.php');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
} else
$client->setAccessToken($_SESSION['access_token']);
$service = new Google_DriveService($client);
//Inserting a file
$file = new Google_DriveFile();
$file->setTitle('Mysheet');
$file->setDescription('My first sheet through php');
$file->setMimeType('application/vnd.google-apps.spreadsheet');
$createdFile = $service->files->insert($file, array(
'mimeType' => 'application/vnd.google-apps.spreadsheet',
'uploadType' => 'multipart'
));
print_r($createdFile);
} else {
$authUrl = $client->createAuthUrl();
header('Location: ' . $authUrl);
exit();
}
?>

You have to create a new service, before you authenticate the Client:
<?php
// ...
$client = new Google_Client();
$client->setClientId('clientID');
$client->setClientSecret('clientSecret');
$client->setRedirectUri('redirectURI');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
// create Drive service before authentication
$service = new Google_DriveService($client);
if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
} else {
$client->setAccessToken($_SESSION['access_token']);
}
// ...
} else {
// ...
}
Btw: See the simplefileupload example in the google-api-php-client repo.

Related

PHP Google Drive API V3: "Login Required" Error

I'm using Google Drive API v3 in my app. I want to have a simple file upload using the API. But it's giving me an error saying "Login Required" even after logging in and redirected.
gdrive_auth.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('MY CLIENT ID');
$client->setClientSecret('MYS SECRET');
$client->setRedirectUri('http://localhost/gdriveapi/index.php');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
session_start();
if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
} else
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
header('Location: ' . $authUrl);
exit();
}
index.php (to which i'm redirected after authorization)
<?php
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('MY CLIENT ID');
$client->setClientSecret('MY SECRET');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$service = new Google_Service_Drive($client);
//Insert a file
$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid().'.jpg');
$file->setDescription('A test document');
$file->setMimeType('image/png');
$data = file_get_contents('Capture.png');
$createdFile = $service->files->create($file, array(
'data' => $data,
'mimeType' => 'image/png',
'uploadType' => 'multipart'
));
print_r($createdFile);
The error message:
Fatal error: Uncaught Google_Service_Exception: { "error": { "errors":
[ { "domain": "global", "reason": "required", "message": "Login
Required", "locationType": "header", "location": "Authorization" }
Any solution for this?

In my google plus insert an activity using "Domains Google+ API" and PHP. I get error

This is my code to insert an activity:
const SERVICE_ACCOUNT_EMAIL = "xxxxxx";
const KEY_FILE = 'key.p12';
$client_id = 'yyyyyyyyy';
$client_secret = 'zzzzzzzzz';
$redirect_uri = 'ttttttttt';
$client = new Google_Client();
$client->setApplicationName("Prueba_social123");
$key = file_get_contents(KEY_FILE);
$user_credentials = new Google_Auth_AssertionCredentials(
SERVICE_ACCOUNT_EMAIL,
array("https://www.googleapis.com/auth/plus.me",
"https://www.googleapis.com/auth/plus.stream.write"),
$key);
$user_credentials->sub = "xxxxxxxxx#gmail.com";
$client->setAssertionCredentials($user_credentials);
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setDeveloperKey('wwwwwwwwwwwwwwwwwwwwww');
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/plus.login', 'https://www.googleapis.com/auth/plus.stream.write') );
$plus = new Google_Service_Plus($client);
$oauth2 = new Google_Service_Oauth2($client);
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
}
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
$token_data = $client->verifyIdToken()->getAttributes();
$plusdomains = new Google_Service_PlusDomains($client);
$activityObject = new Google_Service_PlusDomains_ActivityObject();
$activityObject->setOriginalContent("Prueba de actividad desde la API de mensajes123");
$activityAccess = new Google_Service_PlusDomains_Acl();
$activityAccess->setDomainRestricted(true);
$resource = new Google_Service_PlusDomains_PlusDomainsAclentryResource();
$resource->setType("public");
$resources = array();
$resources[] = $resource;
$activityAccess->setItems($resources);
$activity = new Google_Service_PlusDomains_Activity();
$activity->setObject($activityObject);
$activity->setAccess($activityAccess);
$plusdomains->activities->insert("me", $activity);
....................
And I get the ERROR:
Fatal error: Uncaught exception 'Google_Service_Exception' with
message 'Error calling POST
https://www.googleapis.com/plusDomains/v1/people/me/activities?key=xxxxxxxxxxxxxxxx:
(403) Forbidden' in
/var/www/html/public/pruebas_sociales/google-api/src/Google/Http/REST.php:79
Stack trace: #0
/var/www/html/public/pruebas_sociales/google-api/src/Google/Http/REST.php(44):
Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request)) #1
/var/www/html/public/pruebas_sociales/google-api/src/Google/Client.php(512):
Google_Http_REST::execute(Object(Google_Client),
Object(Google_Http_Request)) #2
/var/www/html/public/pruebas_sociales/google-api/src/Google/Service/Resource.php(195):
Google_Client->execute(Object(Google_Http_Request)) #3
/var/www/html/public/pruebas_sociales/google-api/src/Google/Service/PlusDomains.php(491):
Google_Service_Resource->call('insert', Array, 'Google_Service_...')
4 /var/www/html/public/pruebas_sociales/google-api/examples/idtoken.php(114):
Google_Service_PlusDomains_Activities_ in
/var/www/html/public/pruebas_sociales/google-api/src/Google/Http/REST.php
on line 79
I'm with the problem from two weeks ago. How I can fix it? Help.

I couldn't connect to Google calender api using v3 php client library

I couldn't connect able to display events,insert events by using php client library.
This is the error i got.
I am using v3 version of client library
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/calendar/v3/calendars/primary?key=****************: (401) Login Required' in /var/www/html/google-api-php-client1/src/Google/Http/REST.php:79
Stack trace:
#0 /var/www/html/google-api-php-client1/src/Google/Http/REST.php(44): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request))
#1 /var/www/html/google-api-php-client1/src/Google/Client.php(503): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#2 /var/www/html/google-api-php-client1/src/Google/Service/Resource.php(195): Google_Client->execute(Object(Google_Http_Request))
#3 /var/www/html/google-api-php-client1/src/Google/Service/Calendar.php(1269): Google_Service_Resource->call('get', Array, 'Google_Service_...')
#4 /var/www/html/simple.php(27): Google_Service_Calendar_Calendars_Resource->get('primary') #5 {main} thrown in /var/www/html/google-api-php-client1/src/Google/Http/REST.php on line 79
since you are getting 401 login required error so you need to set setAccessToken.visit here Error with Google Calendar API - 401 Login required when adding a calendar event
may be you need to issue refreshToken() using the original authenticated access code that contains a refresh token.
// example
$google_client->refreshToken($token->refresh_token);
and use 'setDeveloperKey'. it works.you can see this:https://code.google.com/p/google-api-php-client/issues/detail?id=218
Finally solved problem.
This is the perfect example to get list of events of calender.
<?php
// ...
ini_set('display_errors', 1);
error_reporting(E_ALL);
set_include_path('google-api-php-client1/src');
require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';
//
$client = new Google_Client();
//print_r($client);exit;
//$client->setUseObjects(true);
$client->setApplicationName("your-app-name");
$client->setClientId("CLIENT id");
$client->setClientSecret('CLIENT SECRET');
$client->setDeveloperKey('DEVELOPER KEY');
$client->setRedirectUri('your url mostly localhost');
$client->setScopes(array(
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/calendar.readonly',
));
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
//print_r($_SESSION['token']);exit;
//header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
if (isset($_SESSION['token'])) {
//echo 'innn';exit;
$client->setAccessToken($_SESSION['token']);
//echo 'innn';exit;
}
}
if ($client->getAccessToken()) {
//echo 'innn';exit;
$service = new Google_Service_Calendar($client);
//echo '<pre>'; print_r($service);exit;
//$calendar = $service->calendars->get('primary');
//echo $calendar->getSummary();
$events = $service->events->listEvents('primary');
while(true) {
foreach ($events->getItems() as $event) {
echo $event->getSummary();
}
$pageToken = $events->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$events = $service->events->listEvents('primary', $optParams);
} else {
break;
}
}
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
Script to add event.
Actual problem is Google Calendar version 3 not matching with its documentation.
So I checked Calender.php for all available classes.
$event = new Google_Service_Calendar_Event();
$event->setSummary('Interview');
$event->setLocation('Hell');
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime('2014-09-04T10:00:00.000-07:00');
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime('2014-09-04T11:00:00.000-07:00');
$event->setEnd($end);
$attendee1 = new Google_Service_Calendar_EventAttendee();
$attendee1->setEmail('email#abc.com');
// ...
$attendees = array($attendee1,
// ...
);
$event->attendees = $attendees;
$createdEvent = $service->events->insert('primary', $event);
echo $createdEvent->getId();

Google OAuth 2.0 refresh token for web application with public access

I'm getting the following error:
The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved
I have a web application which only my server will be accessing, the initial auth works fine, but after an hour, the aforementioned error message pops up. My script looks like this:
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("{MY_API_KEY}");
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setClientSecret('{MY_KEY}');
$client->setRedirectUri('{MY_REDIRECT_URI}');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
How can I set up a refresh token for this?
Edit 1: I've tried doing this with a Service account as well. I followed the documentation available on GitHub:
https://github.com/google/google-api-php-client/blob/master/examples/service-account.php
My script looks like this:
session_start();
include_once "templates/base.php";
require_once 'Google/Client.php';
require_once 'Google/Service/Gmail.php';
$client_id = '{MY_CLIENT_ID}.apps.googleusercontent.com';
$service_account_name = '{MY_EMAIL_ADDRESS}#developer.gserviceaccount.com ';
$key_file_location = 'Google/{MY_KEY_FILE}.p12';
echo pageHeader("Service Account Access");
if ($client_id == ''
|| !strlen($service_account_name)
|| !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
}
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$service = new Google_Service_Gmail($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/gmail.readonly'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
This returns the following message:
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }''
After tracking this code to it's source, which can be found in Google/Auth/OAuth2.php
The method in question, refreshTokenRequest:
private function refreshTokenRequest($params)
{
$http = new Google_Http_Request(
self::OAUTH2_TOKEN_URI,
'POST',
array(),
$params
);
$http->disableGzip();
$request = $this->client->getIo()->makeRequest($http);
$code = $request->getResponseHttpCode();
$body = $request->getResponseBody();
if (200 == $code) {
$token = json_decode($body, true);
if ($token == null) {
throw new Google_Auth_Exception("Could not json decode the access token");
}
if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
throw new Google_Auth_Exception("Invalid token format");
}
if (isset($token['id_token'])) {
$this->token['id_token'] = $token['id_token'];
}
$this->token['access_token'] = $token['access_token'];
$this->token['expires_in'] = $token['expires_in'];
$this->token['created'] = time();
} else {
throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
}
}
Which means that the $code variable is NULL.
I found this post on SO:
Error refreshing the OAuth2 token { “error” : “invalid_grant” }
And can see that there is still no prefered solution. This is driving me nuts. There is very little to no documentation available on this and if anybody has a solution, I'm sure I'm not the only one looking for it.
Each access_token expires after a few seconds and need to be refreshed by refresh_token, "Offline access" is what you are looking for. Here you can follow the documentation:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
To obtain a refresh_token you have to run this code only one time:
require_once 'Google/Client.php';
$client = new Google_Client();
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setClientSecret('{MY_KEY}');
$client->setRedirectUri('{MY_REDIRECT_URI}');
//next two line added to obtain refresh_token
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
if (isset($_GET['code'])) {
$credentials = $client->authenticate($_GET['code']);
/*TODO: Store $credentials somewhere secure */
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
$credentials includes an access token and a refresh token. You have to store this to obtain new access tokens at any time. So when you wanted to make a call to api:
require_once 'Google/Client.php';
require_once 'Google/Service/Gmail.php';
/*TODO: get stored $credentials */
$client = new Google_Client();
$client->setClientId('{MY_CLIENT_ID}.apps.googleusercontent.com');
$client->setRedirectUri('{MY_REDIRECT_URI}');
$client->setClientSecret('{MY_KEY}');
$client->setScopes(array('https://www.googleapis.com/auth/gmail.readonly'));
$client->setAccessToken($credentials);
$service = new Google_Service_Gmail($client);

Google Admin SDK in PHP

I am using the following code to retrieve the list of users associated with my google apps account.
There is no problem with authentication but when the redirection made this error is appearing.
index.php
<?php
require_once 'test_user/src/Google_Client.php';
require_once 'test_user/src/contrib/Google_PlusService.php';
require_once 'test_user/src/contrib/Google_Oauth2Service.php';
require_once 'test_user/src/contrib/Google_DirectoryService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("ApplicationName");
//*********** Replace with Your API Credentials **************
$client->setClientId('****');
$client->setClientSecret('****');
$client->setRedirectUri('****');
$client->setDeveloperKey('****');
//************************************************************
$client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/admin.directory.user.readonly'));
$plus = new Google_PlusService($client);
$oauth2 = new Google_Oauth2Service($client); // Call the OAuth2 class for get email address
$adminService = new Google_DirectoryService($client); // Call directory API
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
}
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['access_token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
}
if ($client->getAccessToken())
{
$user = $oauth2->userinfo->get();
$me = $plus->people->get('me');
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2
$optParams = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $optParams);
//$users = $adminService->users->get($email);
$list_users = $adminService->users->listUsers();
print '<h2>Response Result:</h2><pre>' . print_r($list_users, true) . '</pre>';
$_SESSION['access_token'] = $client->getAccessToken();
}
else
{
$authUrl = $client->createAuthUrl();
header("location:$authUrl");
}
?>
error i'm getting:
Fatal error: Uncaught exception 'Google_ServiceException' with message 'Error calling
GET https://www.googleapis.com/admin/directory/v1/users?
key=AIzaSyBp0yBFCCosu113tbNbw7yAIjIt1ndFFIs: (400) Bad Request' in
/var/www/vhosts/vx44.com/httpdocs/test_user/src/io/Google_REST.php:66 Stack trace: #0
/var/www/vhosts/vx44.com/httpdocs/test_user/src/io/Google_REST.php(36):
Google_REST::decodeHttpResponse(Object(Google_HttpRequest)) #1
/var/www/vhosts/vx44.com/httpdocs/test_user/src/service/Google_ServiceResource.php(186):
Google_REST::execute(Object(Google_HttpRequest)) #2
/var/www/vhosts/vx44.com/httpdocs/test_user/src/contrib/Google_DirectoryService.php(695):
Google_ServiceResource->__call('list', Array) #3
/var/www/vhosts/vx44.com/httpdocs/test_user/test_user.php(52):
Google_UsersServiceResource->listUsers('nelson302.com') #4 {main} thrown in/var/www/vhosts/vx44.com/httpdocs/test_user/src/io/Google_REST.php on line 66
Note that i've enabled Admin SDK on Google APIs Console.
What am i doing wrong here? thank you for helping
Try replacing:
$list_users = $adminService->users->listUsers();
with:
$adminOptParams = array('customer' => 'my_customer');
$list_users = $adminService->users->listUsers($adminOptParams);
this is explained in the Admin SDK Developer's Guide.

Categories