1

I have an application and when I try to connect on Google Spreadsheets, during connection, I got the message "You need permission"!

I use this code below to getSpredsheets:

try{
            $spreadsheetFeed = null;
            
            $auth_url = '';
            
            $db->setQuery("Select password From #__breezingforms_addons_gdata Where form_id = " . intval($form_id));
         $accessToken = $db->loadResult();
          // $accessToken='{"access_token":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","scope":"https:\/\/www.googleapis.com\/auth\/spreadsheets","token_type":"Bearer","created":434345842294}';

            if(!$accessToken){
                
                $auth_url = $this->client->createAuthUrl();
                
            } else {
                
                try{
                    $this->client->setAccessToken($accessToken);
                    $token = json_decode($accessToken);
            
                    if ($this->client->isAccessTokenExpired()) {
                        $this->client->refreshToken($token->refresh_token);
                        $tok = json_encode($this->client->getAccessToken());
                        $token = json_decode($tok);
                        $db->setQuery("Update #__breezingforms_addons_gdata set password = " . $db->quote($tok) . " Where form_id = " . intval($form_id));
                        $db->execute();
                    }
                    
                    $serviceRequest = new DefaultServiceRequest($token->access_token, $token->token_type);
                    ServiceRequestFactory::setInstance($serviceRequest);

                    $spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
                    $spreadsheetFeed = $spreadsheetService->getSpreadsheets();
                    
                }catch(Exception $ee){
                    
                  //$accessToken = null;
                    //$auth_url = $this->client->createAuthUrl();
          $error=$ee->getMessage();
                              
                              }
            }

            if($spreadsheetFeed !== null){
                foreach($spreadsheetFeed As $sheet){
                    $gdata_spreadsheets[$sheet->getId()] = $sheet->getTitle();
                }
            }
            
            if($gdata->spreadsheet_id != '' && isset( $gdata_spreadsheets[$gdata->spreadsheet_id] ) && $spreadsheetFeed !== null){

                $spreadsheet = $spreadsheetFeed->getByTitle($gdata_spreadsheets[$gdata->spreadsheet_id]);
                $worksheetFeed = $spreadsheet->getWorksheets();
                
                foreach ( $worksheetFeed as $sheet ){
                    $gdata_worksheets[$sheet->getId()] = $sheet->getTitle();
                }
                
                if($gdata->worksheet_id != '' && isset( $gdata_worksheets[$gdata->worksheet_id] )){
                    
                    $worksheet = $worksheetFeed->getByTitle($gdata_worksheets[$gdata->worksheet_id]);
                    $cellFeed = $worksheet->getCellFeed();

                    foreach($cellFeed->getEntries() as $cellEntry) {
                        
                        $row = $cellEntry->getRow();
                        $col = $cellEntry->getColumn();
                        
                        if( $row > 1 ){
                            break;
                        }
                        
                        $gdata_columns[] = $cellFeed->getCell($row, $col)->getContent();
                        
                    }
                }
            }
        
        } catch(Exception $e){
            
            $error = $e->getMessage();
        }
    //}

In this pieces of code:

$spreadsheetFeed = $spreadsheetService->getSpreadsheets();

Class getSpreadsheets() is for getting the number of spreadsheets, and content of class is :

public function getSpreadsheets()
{
    return new SpreadsheetFeed(
        ServiceRequestFactory::getInstance()->get('feeds/spreadsheets/private/full')
    );
}

I always get the message "you need permission", I'm the owner of my spreadsheets on google drive, I do not know why I got that error message?

I think that the problem is on-site Google account with permissions, but I can not find where I can modify it? Whether someone knows what can cause this?

if I want access to spreadsheet with id:

 public function getSpreadsheetById($id)
{
        
    return new Spreadsheet(
        new SimpleXMLElement(
                            
            ServiceRequestFactory::getInstance()->get('feeds/spreadsheets/private/full/'. $id)
        )
    );
}

Then call that method:

   $serviceRequest = new DefaultServiceRequest($token->access_token, $token->token_type);
                    ServiceRequestFactory::setInstance($serviceRequest);

                    $spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
                    //$spreadsheetFeed = $spreadsheetService->getSpreadsheets();
                    $spreadsheetFeed = $spreadsheetService->getSpreadsheetById("1Bu6CjCDN-cjvkyE8F-YyI8V73Zz8a7NkQibKB5Nfirg");

As I see, I found that spreadsheet on my drive, but I can not access to her, "You need permission".

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
mirec
  • 147
  • 1
  • 1
  • 7
  • Please edit your question and include [example] we need to see your authorzation code. as well as the full error message. TIP: $token->access_token <-- the user who created that access token does not have permission. – Linda Lawton - DaImTo Nov 03 '21 at 09:27
  • Did you set in your program the credentials to access that file? – FourBars Nov 03 '21 at 09:36
  • I allowed my app that can access my account, I was given permission to her! – mirec Nov 03 '21 at 09:38
  • Hi FourBars, yes I set credentials, of course! tnx – mirec Nov 03 '21 at 09:39
  • @mirec how did you allow our app to access your account exactly. This is called authorizaton when you login your app as the access of the user who is authorizing your application to access their data not your data. – Linda Lawton - DaImTo Nov 03 '21 at 10:25
  • @mirec What exactly are you trying to do? Are you trying to access sheets owned by the users of your application. Or are you trying to allow users of your application to access a central sheet owned by you the developer? You say you own it are you logging in with that user that owns it or are you logging in as a diffrent user? – Linda Lawton - DaImTo Nov 03 '21 at 10:28
  • @DaImTo I will try to explain to you the workflow of app! When I try to access to a spreadsheet on my Google drive, I got a message from Google, do I allow access from that application, and I confirm that I allowed that app can edit, delete, create a spreadsheet, it parts is ok! Because app always asks before connecting to google drive for access to edit and other stuff. – mirec Nov 03 '21 at 10:43
  • As I see I successfully connect on my google drive I find that spreadsheet, but I can't access to her. I teste that on that I changes id of spreadsheet and I got an error "Error in Google Request " what means that he can not find her, because id is wrong, if I set up correct id, then I find spreadsheet but I can not access her, I got the message "you need permission".tnx – mirec Nov 03 '21 at 10:43
  • I think we are having a language issue here. Who are you logging in as. How did you create the access token? Your code can not find the sheet unless the user who logged in and create that access token has access to the sheet. Your code is working. Your using the wrong user. – Linda Lawton - DaImTo Nov 03 '21 at 12:31
  • @DaImTo thank you for your feedback! I understand what you want to say, but I think that is not a problem, because, I send a request to google, then select google account, and then my app create credentials based on my account then I get a message from my google account, whether I asked to connect BF application to connect on my account, and when I allow it, I can see that my app has access to my account for edit Google docs. It automatic process that based on selected google account to create credentials, it is oke I think! Thank you! – mirec Nov 03 '21 at 14:33
  • What i am trying to tell you is that your doing it wrong. "connect BF application to connect on my account" <-- it doesn't connect to your account it connects to the users account. If the user doesnt have access its not going to work. Login with a user that has access. – Linda Lawton - DaImTo Nov 03 '21 at 14:37
  • @DaImTo thank you very much for your feedback! Ok, I understand, I will create credentials with my account and then test, and I will let you know whether I succeed! You help me a lot, thank you very much! :) – mirec Nov 03 '21 at 15:09
  • I think you may want to look into [service accounts](https://youtu.be/UTTTtwb7x7g). Im just guessing since you still havent told me exactly what your trying to do. – Linda Lawton - DaImTo Nov 03 '21 at 15:13
  • @DaImTo I create a plugin for the app which connect to Google drive and transferring data from an application to a spreadsheet. I solved everything and now I get stuck on this "you need permission"! I have one question -> Why I can see in my Google account that my application has permission to read, edit, delete google doc (if you said that I use the credentials of another user) ? – mirec Nov 03 '21 at 15:40
  • Is it possible to have a screenshot of the error? – Jose Vasquez Nov 05 '21 at 15:55
  • Hi @ Jose Vasquez I only got "you need permission"! it is all! tnx – mirec Nov 05 '21 at 16:09

1 Answers1

2

I think you have completely missunderstood how Oauth2 works.

You keep asking Why I can see in my Google account that my application has permission to read.

That's Not how Oauth2 works. Your application by default has access to nothing. It is not a user.

When your application runs for the first time. It will display a login and a consent screen to who ever runs your application. If they accept your request for consent you will be able to access the users account. In this case the users drive account.

This is the code which would set up an oauth2 client. When the code runs it will request consent of the user to access Google drive. I can see that due to the scope requested being "https://www.googleapis.com/auth/drive"

$client = new Google\Client();
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/drive");
$service = new Google\Service\Drive($client);

When this code runs it will request that permission of the user and an access token will be returned. That access token will grant access to that users data.

You still have not shown how you have created this access token you appear to be loading into your system. So how ever your access token was created that is the account you can access. Remember access tokens are only valid for an hour.

If you run an about.get using that access token you should be able to see who is the owner of that drive account.

You can also run a file.list to see which files that user has access to.

"You need permission"! most often means that the user does not have access to read that file. Normally though it would be a 404 file not found.

So the user does not have access to that file.

what i think you are doing.

I create a plugin for the app which connect to Google drive and transferring data from an application to a spreadsheet.

It really sounds to me like you have a standard file you are trying to let your application read from and access for your users. You should look into using a service account.

This video explains what a service account is : Should you be using a Google service account after in 2021?

This will show you how to create a Service account credetinals

Here is some code showing how service account authentication works ServiceAccount.php

require_once __DIR__ . '/vendor/autoload.php';

// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');

/**
 * Gets the Google client refreshing auth if needed.
 * Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
 * Initializes a client object.
 * @return A google client object.
 */
function getGoogleClient() {
    return getServiceAccountClient();
}

/**
 * Builds the Google client object.
 * Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
 * Scopes will need to be changed depending upon the API's being accessed. 
 * array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
 * List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
 * @return A google client object.
 */
function getServiceAccountClient() {
    try {   
        // Create and configure a new client object.        
        $client = new Google_Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope([YOUR SCOPES HERE]);
        return $client;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • Hi @DaImTo thank you for everything! I created an access token from my google account, and again I got you "you need permission"! I do as you said to me! I used client id and Client secret from the google account where I want to connect, I do as you said, but again same things! do you know what I do wrong? hmm – mirec Nov 05 '21 at 15:33
  • Client id and client secret have nothing to do with access. Its the user who logs in that grants you access. Login with the user with access. – Linda Lawton - DaImTo Nov 05 '21 at 15:43
  • Hi @DaImTo I need to read more about this stuff on the web documentation and I will back to you, but I'm so nearly that works all! :) Thank you for your help! :) – mirec Nov 05 '21 at 16:06
  • Hi @DalmTo I found where is the problem, I use spreads API v3 which is turned off (what is causes 404 errors), I need make migrate on V4, do you know the best what how to do it?tnx – mirec Nov 23 '21 at 10:16
  • My code uses v4 and it works fine. You cant really migrate from v3 its a completely different system. Your looking at a rewrite. – Linda Lawton - DaImTo Nov 23 '21 at 10:26
  • Hi DaImTo, what do you suggest to me, what is the best way to do it? tnx :) – mirec Nov 23 '21 at 10:35
  • 1
    Start from the beginning [sheets api quickstart php](https://developers.google.com/sheets/api/quickstart/php) – Linda Lawton - DaImTo Nov 23 '21 at 10:38
  • oke, thank you very much for your feedback! Best regards! :) – mirec Nov 23 '21 at 10:47
  • remember to accept the anwser if it helped you. you will also get ponts. – Linda Lawton - DaImTo Nov 23 '21 at 10:54