mirec
mirec

Reputation: 197

When accessing a google spreadsheets i get "You need permission"

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".

Upvotes: 1

Views: 964

Answers (1)

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 117281

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();
    }
}

Upvotes: 2

Related Questions