Доступ к веб-API Picasa с помощью PHP

Кто-нибудь здесь знает, как получить доступ к API Google Фото теперь, когда Google начал использовать OAuth2? Клиентская библиотека PHP на их веб-сайте разработчика устарела и не работает!

Я использовал OAuth для работы с Google Диском, но фотографии не работают! :(

Сначала я использую Google_Client для успешной аутентификации пользователя. Затем на странице перенаправления я пытаюсь выполнить следующее:

require_once("Google/Client.php");

//set up path for Zend GData, because Google Documentation uses that lib
$clientLibraryPath = '/path/to/ZendGData/library';
$oldPath = set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Photos');

try
{
    $authCode = $_GET['code']; //authorization code returned from google

    //next create google OAuth Client object and validate...
    $webAuth= new Google_Client();
    $webAuth->setClientId($clientId);
    $webAuth->setClientSecret($clientSecret);
    $webAuth->authenticate($authCode); //this authenticate() works fine...

    //now my problem is HOW do I tie this to GData API for Picasa :(
    //I tried following but it throws error 
    //*Token invalid - Invalid token: Request token used when not allowed.*

    $client = Zend_Gdata_AuthSub::getHttpClient($authCode);     
    $gp = new Zend_Gdata_Photos($client, "GData:2.0");
    $userFeed = $gp->getUserFeed("default");

Я также пробовал кучу сторонних библиотек, пытался подключить мой $webAuth к Zend_GData_Photos всеми возможными способами ... Я даже пробовал необработанные вызовы curl, но ничего не работает!

Кто-нибудь может мне помочь? Я в своем уме... Я не могу поверить, что Google оставил полностью функциональную библиотеку (PicasaWeb PHP API Ver 1.0) висящей вот так, когда они обновили свою аутентификацию до OAuth.


person Undefined Variable    schedule 09.06.2015    source источник


Ответы (1)


У меня была та же проблема, но, наконец, я снова заработал. Лучше всего то, что вам не нужна никакая клиентская библиотека, чтобы получить доступ к личным фотографиям.

Я потратил два дня, пытаясь заставить его работать с «служебной учетной записью», но безуспешно.

Затем я нашел эту страницу: https://holtstrom.com/michael/blog/post/522/Google-OAuth2-with-PicasaWeb.html

которые помогли мне добиться того, чего я хотел. Это довольно длинная статья, но разобраться в ней и заставить ее работать не займет много времени. В основном вам нужно будет использовать «Идентификатор клиента OAuth 2.0» вместо «Учетная запись службы» в вашем проекте по адресу https://console.developers.google.com В вашем идентификаторе клиента OAuth 2.0 будет указана следующая информация:

  • Идентификатор клиента (something-random.apps.googleusercontent.com)
  • Секрет клиента (случайный секрет клиента)
  • Имя (www.yoursite.com)
  • Авторизованные источники JavaScript (https://www.yoursite.com)
  • Разрешенные URI перенаправления (https://www.yoursite.com/oauth2.php)

Вы будете использовать эти данные в процессе проверки. Прежде чем начать, вам необходимо заполнить экран согласия OAuth.

В этом руководстве есть примечание о хранении этих токенов в БД, но в этом случае я бы предпочел отображать их непосредственно на веб-странице. Это намного проще. Есть предложение использовать https, а не http, но он должен работать на обоих. Я использовал https для своего приложения.

Это сокращенная версия статьи по ссылке выше.

  1. Создайте файл oauth2.php и поместите его на https://www.yoursite.com/oauth2.php

    <?php
    if (isset($_GET['code']))
    {
    $clientId = 'your-client-id.apps.googleusercontent.com';
    $clientSecret = 'your-client-secret';
    $referer = 'https://www.yoursite.com/oauth2.php';
    
    $postBody = 'code='.urlencode($_GET['code'])
              .'&grant_type=authorization_code'
              .'&redirect_uri='.urlencode($referer)
              .'&client_id='.urlencode($clientId)
              .'&client_secret='.urlencode($clientSecret);
    
    $curl = curl_init();
    curl_setopt_array( $curl,
                     array( CURLOPT_CUSTOMREQUEST => 'POST'
                           , CURLOPT_URL => 'https://accounts.google.com/o/oauth2/token'
                           , CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
                                                         , 'Content-Length: '.strlen($postBody)
                                                         , 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
                                                         )
                           , CURLOPT_POSTFIELDS => $postBody                              
                           , CURLOPT_REFERER => $referer
                           , CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
                           , CURLOPT_TIMEOUT => 15 // max seconds to wait
                           , CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
                           , CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
                           , CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
                           , CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
                     ) );
    $response = curl_exec($curl);
    $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);  
    echo($response);
    echo($http_code);
    }
    else { echo 'Code was not provided.'; }
    ?>
    
  2. Подготовьте и перейдите по этой ссылке: https://accounts.google.com/o/oauth2/auth?scope=https://picasaweb.google.com/data/&response_type=code&access_type=offline&redirect_uri=https://www.yoursite.com/oauth2.php&approval_prompt=force&client_id=your-client-id.googleusercontent.com

поля для настройки: redirect_uri и client_id

  1. После перехода по ссылке из шага 2 вы должны увидеть свой экран согласия, где вам нужно будет подтвердить его, и вы будете перенаправлены на свою страницу oauth.php, но на этот раз с параметром code:

https://www.yoursite.com/oauth2.php?code=some-random-code

  1. Затем параметр 'code' будет отправлен oauth.php по адресу: https://accounts.google.com/o/oauth2/token

который вернет (распечатает) данные в формате json, содержащие: access_token, token_type, expires_in и refresh_token.

Код ответа Http должен быть 200. Access_token будет использоваться для получения данных личных альбомов.

  1. Создайте index.php с содержимым:

    <?php
    $curl = curl_init();
    $url = 'https://picasaweb.google.com/data/entry/api/user/default';
    curl_setopt_array( $curl, 
                     array( CURLOPT_CUSTOMREQUEST => 'GET'
                           , CURLOPT_URL => $url
                           , CURLOPT_HTTPHEADER => array( 'GData-Version: 2'
                                                         , 'Authorization: Bearer '.'your-access-token' )
    
                           , CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
                     ) );
    $response = curl_exec($curl);
    $http_code = curl_getinfo($curl,CURLINFO_HTTP_CODE);
    curl_close($curl);
    
    echo($response . '<br/>');
    echo($http_code);
    ?>
    
  2. После запуска скрипта из шага 5 вы должны получить фид по умолчанию от API picasaweb. Когда я говорю «по умолчанию», это означает «по умолчанию», когда вы вошли в систему, то есть с личными альбомами. С этого момента вы сможете использовать этот подход для получения доступа к своей библиотеке фотографий Picasa.

  3. Токен доступа истечет через 3600 секунд (1 час), поэтому вам придется получить новый. это может быть достигнуто с помощью скрипта, подобного приведенному ниже:

    $clientId = 'your-client-id.apps.googleusercontent.com';
    $clientSecret = 'your-client-secret';
    $referer = 'https://www.yoursite.com/oauth2.php';
    $refreshToken = 'your-refresh-token';
    
    $postBody = 'client_id='.urlencode($clientId)
                  .'&client_secret='.urlencode($clientSecret)
                  .'&refresh_token='.urlencode($refreshToken)
                  .'&grant_type=refresh_token';
    
        $curl = curl_init();
        curl_setopt_array( $curl,
                         array( CURLOPT_CUSTOMREQUEST => 'POST'
                               , CURLOPT_URL => 'https://www.googleapis.com/oauth2/v3/token'
                               , CURLOPT_HTTPHEADER => array( 'Content-Type: application/x-www-form-urlencoded'
                                                             , 'Content-Length: '.strlen($postBody)
                                                             , 'User-Agent: www.yoursite.com/0.1 +https://www.yoursite.com/'
                                                             )
                               , CURLOPT_POSTFIELDS => $postBody                              
                               , CURLOPT_RETURNTRANSFER => 1 // means output will be a return value from curl_exec() instead of simply echoed
                               , CURLOPT_TIMEOUT => 15 // max seconds to wait
                               , CURLOPT_FOLLOWLOCATION => 0 // don't follow any Location headers, use only the CURLOPT_URL, this is for security
                               , CURLOPT_FAILONERROR => 0 // do not fail verbosely fi the http_code is an error, this is for security
                               , CURLOPT_SSL_VERIFYPEER => 1 // do verify the SSL of CURLOPT_URL, this is for security
                               , CURLOPT_VERBOSE => 0 // don't output verbosely to stderr, this is for security
                         ) );
        $response = curl_exec($curl);
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);  
    
        if (strlen($response) < 1)
        { echo('fail 01'); }
    
        $NOW = time();
        $responseDecoded = json_decode($response, true); // convert returned objects into associative arrays
        $expires = $NOW - 60 + intval($responseDecoded['expires_in']);
        if ( empty($responseDecoded['access_token'])
          || $expires <= $NOW )
        { echo('fail 02'); }
        echo($http_code . '<br/>');
        echo($response . '<br/>');
        echo($expires . '<br/>');
    ?>
    
  4. Вы можете запустить код из шага 7. в отдельном скрипте вручную, просто чтобы получить новый токен доступа еще на 3600 секунд, но обычно вы хотели бы, чтобы он был автоматизирован, поэтому, когда срок действия access_token истекает, вы автоматически запрашиваете новый, используя вызов с refresh_token с шага 4.

  5. Уффф. То есть. Я надеюсь, что вы получите это и работает.

person Wojciech Jakubas    schedule 05.11.2015