访问谷歌电子表格时,我得到“您需要许可”

Posted

技术标签:

【中文标题】访问谷歌电子表格时,我得到“您需要许可”【英文标题】:When accessing a google spreadsheets i get "You need permission" 【发布时间】:2021-12-17 16:15:55 【问题描述】:

我有一个应用程序,当我尝试在 Google 电子表格上连接时,在连接过程中,我收到了“您需要许可”的消息!

我使用下面的代码来获取Spredsheets:

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

在这段代码中:

$spreadsheetFeed = $spreadsheetService->getSpreadsheets();

类 getSpreadsheets() 用于获取电子表格的数量,类的内容是:

public function getSpreadsheets()

    return new SpreadsheetFeed(
        ServiceRequestFactory::getInstance()->get('feeds/spreadsheets/private/full')
    );

我总是收到消息 "you need permission",我是我在 Google Drive 上的电子表格的所有者,我不知道为什么会收到该错误消息?

我认为问题在于具有权限的现场谷歌帐户,但我找不到可以修改的地方? 是否有人知道是什么原因造成的?

如果我想访问带有 id 的电子表格:

 public function getSpreadsheetById($id)

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

然后调用那个方法:

   $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");

如我所见,我在我的驱动器上找到了那个电子表格,但我无法访问她,“你需要权限”。

【问题讨论】:

请编辑您的问题并包含minimal reproducible example 我们需要查看您的授权码。以及完整的错误消息。提示:$token->access_token 您是否在程序中设置了访问该文件的凭据? 我允许我的应用程序可以访问我的帐户,我获得了她的权限! 嗨 FourBars,是的,我当然设置了凭据! tnx @mirec 您是如何允许我们的应用程序准确访问您的帐户的。当您以授权您的应用程序访问他们的数据而不是您的数据的用户的访问权限登录您的应用程序时,这称为授权。 【参考方案1】:

我认为您完全误解了 Oauth2 的工作原理。

你一直在问Why I can see in my Google account that my application has permission to read.

这不是 Oauth2 的工作方式。默认情况下,您的应用程序无法访问任何内容。它不是用户。

当您的应用程序第一次运行时。它将向曾经运行您的应用程序的人显示登录和同意屏幕。如果他们接受您的同意请求,您将能够访问用户帐户。在这种情况下,用户驱动帐户。

这是设置 oauth2 客户端的代码。当代码运行时,它将请求用户同意访问谷歌驱动器。我可以看到由于请求的范围是"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);

当此代码运行时,它将请求用户的权限,并返回访问令牌。该访问令牌将授予对该用户数据的访问权限。

您仍然没有显示您是如何创建此访问令牌的,您似乎正在加载到您的系统中。因此,您的访问令牌是如何创建的,即您可以访问的帐户。请记住访问令牌仅在一个小时内有效。

如果您使用该访问令牌运行about.get,您应该能够看到谁是该驱动器帐户的所有者。

您还可以运行file.list 来查看用户有权访问哪些文件。

"You need permission"! 通常意味着用户无权读取该文件。通常虽然它会是一个未找到的 404 文件。

因此用户无权访问该文件。

我认为你在做什么。

我为连接到 Google 驱动器并将数据从应用程序传输到电子表格的应用程序创建了一个插件。

在我看来,您确实有一个标准文件,您正试图让您的应用程序从您的用户读取和访问。您应该考虑使用服务帐户。

此视频解释了服务帐户是什么:Should you be using a Google service account after in 2021?

这将向您展示如何创建Service account credetinals

这里有一些代码显示了服务帐户身份验证的工作原理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();
    

【讨论】:

嗨@DaImTo 谢谢你所做的一切!我从我的谷歌帐户创建了一个访问令牌,我再次得到你“你需要许可”!我照你说的做!我使用了我想连接的谷歌帐户中的客户端 ID 和客户端密码,我按照你说的做,但同样的事情!你知道我做错了什么吗?嗯 客户端ID和客户端密码与访问无关。它是授予您访问权限的登录用户。使用具有访问权限的用户登录。 嗨@DaImTo 我需要在网络文档上阅读更多关于这些东西的信息,我会回复你,但我几乎可以全部使用! :) 谢谢您的帮助! :) 嗨@DalmTo 我发现问题出在哪里,我使用已关闭的spreads API v3(导致404错误的原因),我需要在V4上进行迁移,你知道最好的方法吗做吗?tnx 从头开始sheets api quickstart php

以上是关于访问谷歌电子表格时,我得到“您需要许可”的主要内容,如果未能解决你的问题,请参考以下文章

如何在电子表格中的日历谷歌中获得执行操作的权限

从远程 onedit 可安装触发器访问其他谷歌电子表格

通过在云中运行的笔记本从谷歌驱动器访问电子表格文件

访问由电子表格支持的 bigquery 表时遇到 BadRequest/ForbiddenException

插入新行时在谷歌电子表格上触发脚本

无法从谷歌电子表格中读取