【问题标题】:zend gdata picasa php api stopped workingzend gdata picasa php api停止工作
【发布时间】:2015-08-09 13:42:24
【问题描述】:

我已经使用 Zend Gdata 好几年了。

但是,今天当我未更改的代码执行以下命令时

$query = $this->gp->newAlbumQuery();

我收到以下错误

exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 403 Authorization required' in /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata/App.php:717 Stack trace: #0 /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata.php(221): Zend_Gdata_App->performHttpRequest('GET', 'https://picasaw...', Array, NULL, NULL, NULL) #1 /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata/App.php(883): Zend_Gdata->performHttpRequest('GET', 'https://picasaw...', Array) 

我认为这是因为身份验证失败。我检查了,我的凭据都很好,以下验证成功,无一例外

$client = Zend_Gdata_ClientLogin::getHttpClient($this->config['username'], 
                                                $this->config['password'], 
                                                Zend_Gdata_Photos::AUTH_SERVICE_NAME);

我看到 Zend Gdata 仍然是 1.12.13 版本。但是最近的发布日期是 20/05/2015。所以我使用这个新版本进行了更新。但是错误还是一样。

所以我只知道我已通过身份验证,但 newAlbumQuery 方法引发了上述异常。

还有其他人在使用 Zend Gdata 时遇到过这个问题吗?有没有人找到修复或解决方法?

【问题讨论】:

    标签: php zend-framework google-api gdata picasa


    【解决方案1】:

    Zend_Gdata 使用 ClientLogin,它已于 2012 年 4 月 20 日弃用并于 2015 年 4 月 20 日关闭。此代码将不再有效,您需要切换到使用 Oauth2。

    【讨论】:

    • 谢谢。我希望 zend gdata 的最新版本(尽管版本相同)将使用 auth2。似乎没有。 Zend 已经更新了除 Gdata 之外的所有库。自 Auth1 以来,Google 还没有为 Picasa 发布过 php api。他们的新客户端 API 不包括 Google+ 照片或 Picasa。这似乎很可怜。还有其他用于 php 的 picasa api 吗?我什么都找不到!
    • 对我来说似乎与 Oauth2 一起工作。 developers.google.com/picasa-web/docs/2.0/… 当前的 php 客户端库不适用于 Gdata api。
    • 是的,完全正确。看来我将不得不使用他们基于原子的 picasa api 并使用 xpath 在 php 中解析结果。但如果有人有更好的主意,我真的很想避免这种情况!?.....
    • 没有更好的想法,但对我来说听起来很有趣。
    【解决方案2】:

    我遇到了同样的问题。我的应用程序是我唯一使用的应用程序,因此这是我在自己的应用程序中为自己的用户用 OAuth 替换 ClientLogin 的方法。

    我编写了一个使用 OAuth 的 Zend 客户端类。链接在这里:https://gist.github.com/monkbroc/4251effc7912b9764ca1

    主要困难是第一次执行 OAuth 过程以获得一个刷新令牌,Zend OAuthClient 将转换为可用于请求的访问令牌,但在一小时后过期。上面的 Gist 列出了我采取的步骤。

    【讨论】:

    • 谢谢@monkbroc,你真是太好了。但是,我现在不打算将 Zend 用于任何事情。我以前只用过他们的 Gdata 东西,他们让它腐烂的方式令人震惊。我打算自己写一些使用 google-api-php-client 的东西。
    【解决方案3】:

    最后我以这样的方式结束(到目前为止非常原始的代码,但对于那些正在寻找解决方案的人来说已经足够了。您需要https://github.com/asimlqt/php-google-spreadsheet-client 的 php google 电子表格客户端)。那是在我的电子表格中插入一行的小例子(对不起我的代码,但只显示了工作示例) 感谢 bram brambring 展示了更好的授权方式 - answer by bram brambring

    <?php
    /*
     * Google Spreadsheet class to work with google spreadsheets obviously ;D [using OAuth 2.0, as Zend Gdata is not anymore working]
     */
    
    require_once('/Google/Spreadsheet/ServiceRequestInterface.php');
    require_once('/Google/Spreadsheet/DefaultServiceRequest.php');
    require_once('/Google/Spreadsheet/ServiceRequestFactory.php');
    require_once('/Google/Spreadsheet/Spreadsheet.php');
    require_once('/Google/Spreadsheet/SpreadsheetFeed.php');
    require_once('/Google/Spreadsheet/SpreadsheetService.php');
    require_once('/Google/Spreadsheet/Exception.php');
    require_once('/Google/Spreadsheet/UnauthorizedException.php');
    require_once('/Google/Spreadsheet/Spreadsheet.php');
    require_once('/Google/Spreadsheet/Util.php');
    require_once('/Google/Spreadsheet/Worksheet.php');
    require_once('/Google/Spreadsheet/WorksheetFeed.php');
    require_once('/Google/Spreadsheet/ListFeed.php');
    require_once('/Google/Spreadsheet/ListEntry.php');
    require_once('/Google/Spreadsheet/CellFeed.php');
    require_once('/Google/Spreadsheet/CellEntry.php');
    require_once('/Google/Config.php');
    require_once('/Google/Client.php');
    require_once('/Google/Auth/Abstract.php');
    require_once('/Google/Auth/OAuth2.php');
    require_once('/Google/Http/Request.php');
    require_once('/Google/Utils.php');
    require_once('/Google/IO/Abstract.php');
    require_once('/Google/IO/Curl.php');
    require_once('/Google/Http/CacheParser.php');
    require_once('/Google/Logger/Abstract.php');
    require_once('/Google/Logger/Null.php');
    require_once('/Google/Exception.php');
    require_once('/Google/Auth/Exception.php');
    require_once('/Google/Auth/AssertionCredentials.php');
    require_once('/Google/Cache/Abstract.php');
    require_once('/Google/Cache/File.php');
    require_once('/Google/Signer/Abstract.php');
    require_once('/Google/Signer/P12.php');
    
    use Google\Spreadsheet\DefaultServiceRequest;
    use Google\Spreadsheet\ServiceRequestFactory;
    
    class Google_Spreadsheet
    {
        private $default = array(
            'worksheetCols' => 12,
            'worksheetRows' => 25
        );
    
        private $spreadsheetKey;
        private $spreadsheetName;
        private $worksheetName;
        private $spreadsheetFeed;
    
        public $initialized = true;
    
        public function __construct($spreadsheetKey, $worksheetName, $spreadsheetName = '')
        {
            $this->spreadsheetKey = $spreadsheetKey;
            $this->worksheetName = $worksheetName;
            $this->spreadsheetName = $spreadsheetName;
    
            $this->initialized = $this->initialize();
            return true;
        }
    
        private function getToken() {
            $client_email = '318977712937456456454656563tcfjblgoi@developer.gserviceaccount.com';
            $private_key = file_get_contents('API Project-f10e456456b60.p12');
            $scopes = array('https://spreadsheets.google.com/feeds');
            $credentials = new Google_Auth_AssertionCredentials(
                $client_email,
                $scopes,
                $private_key,
                'notasecret',                                 // Default P12 password
                'http://oauth.net/grant_type/jwt/1.0/bearer' // Default grant type
            );
    
            $client = new Google_Client();
            $client->setAssertionCredentials($credentials);
            if ($client->getAuth()->isAccessTokenExpired()) {
                $client->getAuth()->refreshTokenWithAssertion();
            }
    
            $tokenData = json_decode($client->getAccessToken());
            return $tokenData->access_token;
        }
    
        public function initialize(/*$reInitialized = false*/)
        {
            // load OAuth2 token data - exit if false
            $tokenData = $this->getToken();
            $serviceRequest = new DefaultServiceRequest($tokenData);
            ServiceRequestFactory::setInstance($serviceRequest);
            $spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
            try {
                $spreadsheetFeed = $spreadsheetService->getSpreadsheets();
            } catch (\Google\Spreadsheet\UnauthorizedException $e) {    
                Google_Spreadsheet::warnAdmin($e->getMessage());
                return false;
            }
    
            $this->spreadsheetFeed = $spreadsheetFeed;
            return true;
        }
    
        public function insertRow($rowData, $default_fields = array()) {
            $spreadsheetFeed = $this->spreadsheetFeed;
            $spreadsheet = $this->spreadsheetKey ? $spreadsheetFeed->getByKey($this->spreadsheetKey) : $spreadsheetFeed->getByTitle($this->spreadsheetName);
            if(!$spreadsheet && !empty($this->spreadsheetName)) {
                $spreadsheet = $spreadsheetFeed->getByTitle($this->spreadsheetName);
            }
    
            if(!$spreadsheet) {
                Google_Spreadsheet::warnAdmin('No spreadsheet', serialize($rowData));
                return false;
            }
    
            $worksheetFeed = $spreadsheet->getWorksheets();
            $worksheet = $worksheetFeed->getByTitle($this->worksheetName);
    
            if(!$worksheet) {
                //create worksheet if not exist
                $worksheet = $spreadsheet->addWorksheet($this->worksheetName, $this->default['worksheetRows'], $this->default['worksheetCols']);
    
                $cellFeed = $worksheet->getCellFeed();
                for( $i= 1 ; $i <= $this->default['worksheetCols']; $i++ ) {
                    if(isset($default_fields[$i])) {
                        $cellFeed->editCell(1, $i, $default_fields[$i]);
                    }
                    else {
                        $cellFeed->editCell(1, $i, "head");
                    }
    
                    $cellFeed->editCell(2,$i,"content");
                }
            }
    
            if(!$worksheet) {
                Google_Spreadsheet::warnAdmin('No worksheet', serialize($rowData));
                return false;
            }
    
            $listFeed = $worksheet->getListFeed();
    
            $data = array();
            foreach ($listFeed->getEntries() as $entry) {
                $values = $entry->getValues();
                $data[] = $values;
                break; //only first row needed, as we need keys
            }
    
            $keys = array();
            if(!count($data)) {
                Google_Spreadsheet::warnAdmin('No data', serialize($rowData));
                return false;
            }
    
            foreach ($data[0] as $key => $value) {
                $keys[] = $key;
            }
    
            $newRow = array();
            $count = 0;
            foreach($keys as $key) {
                if(isset($rowData[$count])) {
                    $newRow["$key"] = $rowData[$count];
                }
                else {
                    $newRow["$key"] = '';
                }
    
                $count++;
            }
    
            $listFeed->insert($newRow);
            return true;
        }
    
    
        static function warnAdmin($reason = '', $content = '') {
            //temporal function to warn myself about all the stuff happening wrong :)
    
        }
    }
    

    在我使用的主要模型中:

    $spreadsheet = new Google_Spreadsheet("spreadsheet name or ID", $worksheetname, "My spreadsheet name");
    
            if(!$spreadsheet->initialized) {
                Google_Spreadsheet::warnAdmin('cannot initialize spreadsheet', serialize($rowValues));
            }
    
    
            if(!$spreadsheet->initialized || !$spreadsheet->insertRow($rowValues, $this->default_fields)) {
                Google_Spreadsheet::warnAdmin('failed to insert row ');
            }
    

    @Edit,感谢 bram brambring 的令牌解决方案,似乎比我的更容易。现在像魅力一样工作,我希望他的方式能正常刷新令牌。谢谢老兄!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 2015-07-21
      • 1970-01-01
      • 2013-07-19
      • 1970-01-01
      • 2011-10-08
      相关资源
      最近更新 更多