php Google spreadsheet API "Request had insufficient authentication scopes" - php

i have a Problem with the Spreadsheed api and the "scopes".
With these script i want to update Cells on a Sheet.
I do not work with composer ich have just download the package in intereating it. The Token is already there and the error is from these row:
"$response = $service->spreadsheets_values->get($spreadsheetId, $range);"
<?php
session_start();
require_once __DIR__.'/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig('oauth-credentials.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
$client->setAccessToken($_SESSION['access_token']);
echo "<pre>";
$service = new Google_Service_Sheets($client);
$spreadsheetId = 'xxx';
$range = 'Tabellenblatt1!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (count($values) == 0) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s <br>", $row[0], $row[4]);
}
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/api/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>
These Code brings the following Error
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}

You have this scope defined:
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
For accessing a spreadsheet value:
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
You should have:
$client->addScope(Google_Service_Sheets::SPREADSHEETS_READONLY);
or
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
Source:
https://developers.google.com/identity/protocols/googlescopes#sheetsv4

You Must Update the scope as #random425 said,
but after that delete the Token.json.
that will start the process of verification again what will give you new token with new scope that you have changed to.

Related

I'm trying to get the google calendar id but it is wrong

I'm trying to get the calendar, but it's returning an error
Uncaught Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "notFound", "message": "Not Found" } ], "code": 404, "message": "Not Found" } } in
Below is my code, where I already have the auth2 access token
require "../_lib/libraries/grp/googleCalendar/vendor/autoload.php";
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('../_lib/libraries/grp/googleCalendar/credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
//$_SESSION['access_token'] = '';
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
print_r($_SESSION['access_token']);
// Exchange authorization code for an access token.
//$accessToken = $client->fetchAccessTokenWithAuthCode($_SESSION['access_token']);
$client->setAccessToken($_SESSION['access_token']);
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Exchange authorization code for an access token.
$accessToken = $_SESSION['access_token'];
$client->setAccessToken($accessToken);
}
}
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
//here the error occurs
$calendar = $service->calendars->get('calendarid');
echo $calendar->getSummary();
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'].'/scriptcase9/app/project_gestao/oauth2callback/index.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
it is part of obtaining the access token auth02 is working, but now I need the calendarid and the error returns as I explained above.
as said the access token is already working and is showing events correctly, but I need the calendarid.
Your code contains the line
$calendar = $service->calendars->get('calendarid');
Hereby 'calendarid' should either be replaced by a real id (of a calendar to which you have access!) or through a variable.
Given that before you already defined $calendarId = 'primary'; it makes sense to modify your code to
$calendar = $service->calendars->get($calendarId);

how to upload files to google drive using php with access token

Am trying to upload a files to my google drive account with php and curl. I do not want all these long authentication flow of a thing. To this effect,I implemented the code below
$secret ="xxxxxx";
$clientid ="xxxxxxx";
$ch = curl_init ();
curl_setopt_array ( $ch, array (
CURLOPT_URL => "https://www.googleapis.com/upload/drive/v3/files?uploadType=media&clientID=xxxxxxx&secret=xxxxxxx",
CURLOPT_HTTPHEADER => array (
'Content-Type: image/png'),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => file_get_contents ('iconc.png' ),
CURLOPT_RETURNTRANSFER => 1
) );
$res = curl_exec($ch);
$err = curl_error($ch);
echo $res;
var_dump($res);
echo "<br>";
echo "<br>";
echo $err ;
I have enabled my google Drive Api and I have been assigned client id and secret but when I run the code its saying invalid credentials as per below
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } } string(238) "{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } } "
Please where do I pass the client id and secret in the code above or do i need something like access token. if yes where do I get the google drive API access token. any solution is welcome. Thanks
You have two options the first is to add the access token to the request
https://www.googleapis.com/upload/drive/v3/files?access_token={YourToken}
The second is to add it as a header in the request
curl -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}"
https://www.googleapis.com/upload/drive/v3/files
Using the client id as you have done here clientID=xxxxxxx&secret=xxxxxxx is basic authorization not Oauth2 you are missing the authorization step.
You should consider following the php quickstart here
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
$optParams = array(
'pageSize' => 10,
'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($results->getFiles() as $file) {
printf("%s (%s)\n", $file->getName(), $file->getId());
}
}

Google API PHP Login retrieving Auth Error

I am trying to implement a log in via Google on my application to access some information and control some features of the user Youtube channel but it is returning error all the time, saying that the user is not authenticated.
That's my code.
<?php
session_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'vendor/autoload.php';
$OAUTH2_CLIENT_ID = '-----------------------------------------';
$OAUTH2_CLIENT_SECRET = '-----------------';
$REDIRECT = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$APPNAME = "Test";
try{
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes([
'https://www.googleapis.com/auth/youtube.force-ssl',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/userinfo.profile'
]);
$client->setRedirectUri($REDIRECT);
$client->setApplicationName($APPNAME);
$client->setDeveloperKey('---------------------');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
}
catch(Exception $e){
die('1: '.$e);
}
$youtube = new Google_Service_YouTube($client);
$google_oauth = new Google_Service_Oauth2($client);
$plusAuth = new Google_Service_Plus($client);
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
try{
$client->authenticate($_GET['code']);
$user_email = $google_oauth->userinfo->get()->email;
$user_name = $plusAuth->people->get('me')->displayName;
}
catch(Exception $e){
die('2: '.$e);
}
// Code in between
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
//echo "Access Token: " . json_encode($_SESSION['token']);
header('Location: /main.php');
}
if ($client->getAccessToken()) {
$_SESSION['token'] = $client->getAccessToken();
}
else{
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
header('Location: '.$client->createAuthUrl());
}
?>
And I am getting this error:
2: Google_Service_Exception: { "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "domain": "global", "reason": "unauthorized" } ], "status": "UNAUTHENTICATED" } }
I can't find the reason to the login flow is failing, but when it tries to use the properties of the Google Service Class's it always says that I am not authenticated.
If you can help me I am very welcome.

Unable to Use Google+ API

I was attempting a google sign in using the following code:
<code>
function gLogin(){ //handle the login process for retrieving google User's email with
$client = new Google_Client();
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setScopes(array(Google_Service_Oauth2::USERINFO_EMAIL,Google_Service_Oauth2::USERINFO_PROFILE,Google_Service_Plus::PLUS_ME,Google_Service_Plus::PLUS_LOGIN));
$plus = new Google_Service_Plus($client);
try{
$client->authenticate($_GET['code']);
$me = $plus->people->get('me');
//deal with non-domain Emails
if($me['domain'] !== 'xxx.org' && $me['domain'] !== 'xxx.org'){
$client->revokeToken();
$errorUrl = ERROR_URI . '?error=wrongDomain';
http_response_code(302);
header('Location: ' . $errorUrl);
die();
}
$displayName = $me['displayName'];
//get the email
$oauth = new Google_Service_Oauth2($client);
$emails = $oauth->userinfo->get();
$email = $emails->getEmail();
//too nested, going to sqlLogin
sqlLogin($email, $displayName);
$client->revokeToken();
}catch(Exception $e){
error_log($e->getMessage());
}
}
</code>
When I did, I would get the following error:
{\n "error": {\n "errors": [\n {\n "domain": "usageLimits",\n
"reason": "dailyLimitExceededUnreg",\n "message": "Daily Limit for
Unauthenticated Use Exceeded. Continued use requires signup.",\n
"extendedHelp": "https://code.google.com/apis/console"\n }\n ],\n
"code": 403,\n "message": "Daily Limit for Unauthenticated Use
Exceeded. Continued use requires signup."\n }\n}\n,
Any help would be appreciated
I realized my own error. Since I was redirecting from index.php and not keeping the access token, I had to manually set it with $client->setAccessToken($client->getAccessToken()); (I wasn't keeping the token due to some code standardization that I wanted). Updated code:
$client = new Google_Client();
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setRedirectUri('replace_me'); //not sure if I need the redirectUri here, but it was one of the things I tested
$client->setScopes(array(Google_Service_Oauth2::USERINFO_EMAIL,Google_Service_Oauth2::USERINFO_PROFILE,Google_Service_Plus::PLUS_ME,Google_Service_Plus::PLUS_LOGIN));
try{
$error = $client->authenticate($_GET['code']);
print_r($error);
$client->setAccessToken($client->getAccessToken()); /*access tokens must be requested with the following line if you are not keeping them, otherwise it will be an unauthenticated request*/
$plus = new Google_Service_Plus($client);
$me = $plus->people->get('me');
//deal with non-domain Emails
if($me['domain'] !== 'xxx.org' && $me['domain'] !== 'xxx.org'){
$client->revokeToken();
$errorUrl = ERROR_URI . '?error=notDomain';
http_response_code(302);
header('Location: ' . $errorUrl);
die();
}
$displayName = $me['displayName'];
//get the email
$oauth = new Google_Service_Oauth2($client);
$emails = $oauth->userinfo->get();
$email = $emails->getEmail();
//too nested, going to sqlLogin
sqlLogin($email, $displayName);
$client->revokeToken();
}catch(Exception $e){
error_log($e->getMessage()); }

google sheets api v4 PHP Quickstart Writing to a single range

I can read my Google Sheet Doc use this tutorial: https://developers.google.com/sheets/api/quickstart/php
quickstart.php:
<?php
require_once __DIR__ . '/vendor/autoload.php';
define('APPLICATION_NAME', 'Google Sheets API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/sheets.googleapis.com-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Sheets::SPREADSHEETS_READONLY)
));
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* #param string $path the path to expand.
* #return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Sheets($client);
// Prints the names and majors of students in a sample spreadsheet:
$spreadsheetId = 'myfileid';
$range = 'Class Data!A2';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (count($values) == 0) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s\n", $row[0], $row[4]);
}
}
All is Ok. I can read my Google Sheet Doc. But I need have only one additional possibility: writing to a single range. I added to end of quickstart.php this code:
$values = array(
array(
5
),
// Additional rows ...
);
$body = new Google_Service_Sheets_ValueRange(array(
'values' => $values
));
$params = array(
'valueInputOption' => $valueInputOption
);
$result = $service->spreadsheets_values->update($spreadsheetId, $range,
$body, $params);
frome here: https://developers.google.com/sheets/api/guides/values
I have:
PHP Fatal error:
Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
My Google Sheet Doc has permission for redact/modify. I need have writing to a single range. What is mean this error? Please help me modify quickstart.php.
Change the scopes to Google_Service_Sheets::SPREADSHEETS check,
also try this
$params = array(
'valueInputOption' => $valueInputOption
);
to check
$params = array(
'valueInputOption' => 'USER_ENTERED'
);

Categories