Путаница новичка в Google Drive API (PHP) - какое руководство / библиотеку использовать?

1

У меня есть мобильный сайт m.example.com - с телефона я хочу, чтобы посетители выбирали файл с Google Диска и отправляли его на сервер, на котором размещен файл m.example.com. По сути, эмуляция простой загрузки <input type="file"> как на рабочем столе.

Насколько я понимаю, рабочий процесс выглядит следующим образом:

1) Пользователь выбирает файл с помощью Picker, который отправляет метаданные выбранного файла на мой веб-клиент (т.е. HTML/Javascript, работающий на телефоне/планшете)

2) Я отправляю это на свой сервер через ajax или просто скрытое поле формы

3) мой сервер отправляет запрос в API Google для получения файла, а затем сохраняет его в файловой системе сервера

Поэтому мне нужна помощь:

а) правильные ли эти шаги, и есть ли другой способ сделать это, или даже услугу, которую я могу использовать, что позволит моим пользователям сайта выбирать свои файлы у одного из нескольких провайдеров облачных хранилищ?

а) если мои шаги верны, и это единственный способ, я застрял на 3) частичном сервере, который говорит с API.

До сих пор я закрыл сборщик, как здесь, - всплывающее окно Google picker auth блокируется и получает URL-адрес файла. Я еще не сделал 2), я просто вручную помещаю URL-адрес файла в мой скрипт downlaod.

Я использую PHP, и файл, который я хочу, чтобы downlaod на мой сервер мог быть общедоступным или частным, зависит от конечного пользователя.

Я потерялся в документах API (как в man-страницах, а не в документе google), и я смущен https://developers.google.com/api-client-library/php/start/get_started (вызовите эти документы API) и https://developers.google.com/drive/web/quickstart/quickstart-php (вызов этого документа на Диске) - эти два разных API?

Я следил за ссылками из документов API и устанавливал здесь клиента: https://github.com/google/google-api-php-client, но при попытке "Шаг 3: Настроить образец" в Документах на Диске я получить много ошибок, таких как файлы, которые не были найдены, класс not fount и т.д., так что это заставляет меня думать, что therr - это два разных API/Клиента, задокументированных здесь, - может кто-то, пожалуйста, указать мне в правильном направлении, чтобы начать?

ОБНОВИТЬ

Я установил клиент PHP в github, связанный с этим https://developers.google.com/api-client-library/php/start/get_started.

Это выглядит так:

Изображение 174551

Я запустил файл simplefileupload.php в каталоге примеров - работал в первый раз, мне нужно было только указать подробности моего проекта

Итак, перейдите на страницу https://developers.google.com/drive/web/quickstart/quickstart-php#step_3_set_up_the_sample и создал файл drive_rest_api_step_3.php в корневом каталоге google-api (как показано на экране захвата)

Got Fatal error: require_once(): Failed opening required 'src/Google_Client.php' (include_path='.: /usr/local/lib/php') in/path/to/google-api/drive_rest_api_step_3.php on line 5

В библиотеке нет Google_Client.php, но есть src/Google/Client.php, поэтому я редактирую require_once, чтобы использовать это.

Теперь получите Failed opening required 'src/contrib/Google_DriveService.php' - снова поиск этого файла не дает результатов, но есть src/Google/Service/Drive.php, поэтому используйте пример редактирования:

Требуется (на https://developers.google.com/drive/web/quickstart/quickstart-php#step_3_set_up_the_sample):

require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';

Теперь:

require_once 'src/Google/Client.php';
require_once 'src/Google/Service/Drive.php';

Теперь получение Fatal error: Class 'Google_Service' not found in/path/to/google-api/src/Google/Service/Drive.php on line 32

Поэтому я думаю, что есть проблемы с двумя наборами руководств, либо они используют разные библиотеки, либо https://developers.google.com/drive/web/quickstart/quickstart-php#step_3_set_up_the_sample устарели, хотя сказано Последнее обновление 30 марта 2015 года.

  • 0
    Связанные с вами документы и репозиторий github - это одно и то же, клиентская библиотека PHP для Google Drive. Я сомневаюсь, что это проблема того, что вы используете, и того, как вы это используете. Я предлагаю вам сначала начать с быстрого начала работы. Вы должны будете поделиться любым соответствующим кодом и ошибками, если вам нужна помощь помимо этого. Похоже, у вас, вероятно, нет прав доступа к рассматриваемым файлам.
  • 0
    @Andy Энди - я обновил свой вопрос, показывая больше деталей и ошибок, спасибо!
Теги:
google-drive-sdk

1 ответ

7
Лучший ответ

Вы правы в том, что руководство по быстрому запуску накопителя устарело, оно относится к старой версии Библиотеки API-интерфейсов Google PHP, которая находится в коде Google, а не к новой версии GitHub. Следовательно, руководство по быстрому старту не работает с загруженной вами клиентской библиотекой PHP. Кроме того, код руководства для быстрого запуска предназначен для выполнения в режиме командной строки PHP, а не на сервере.

Чтобы ответить на вопрос, я добавил несколько ответов:

  1. Как использовать клиентскую библиотеку PHP
  2. Как выбрать файл с помощью Google Picker и получить файл на сервере

Использование клиентской библиотеки Google PHP с API-интерфейсом Google Диска

Вместо этого попробуйте использовать эту страницу: https://developers.google.com/api-client-library/php/auth/web-app, в которой показан пример отображения файлов на Google Диске Google с использованием новой библиотеки PHP, включая целая процедура OAuth.

К сожалению, даже это немного устарело (путь включения устарел и теперь устарел). Как таковой (и для полноты StackOverflow) здесь некоторый код. Я использовал подкаталог drivetest в своем корневом веб-сервере; при необходимости измените URL-адреса.

Обратите внимание, что вам нужно получить идентификатор клиента для "Веб-приложений" в консоли разработчика Google и загрузить JSON (при необходимости заменив client_secrets.json в коде).

drivetest/quickstart.php

<?php
    require_once 'google-api-php-client/src/Google/autoload.php';

    session_start();

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json');
    $client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        $client->setAccessToken($_SESSION['access_token']);
        $drive_service = new Google_Service_Drive($client);
        $files_list = $drive_service->files->listFiles(array())->getItems();
        echo json_encode($files_list);
    } else {
        $redirect_uri = 'http://localhost/drivetest/oauth2callback.php';
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }   

?>

drivetest/oauth2callback.php

<?php
    require_once 'google-api-php-client/src/Google/autoload.php';

    session_start();

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json');
    $client->setRedirectUri('http://localhost/drivetest/oauth2callback.php');
    $client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

    if (! isset($_GET['code'])) {
        $auth_url = $client->createAuthUrl();
        header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    } else {
        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
        $redirect_uri = 'http://localhost/drivetest/quickstart.php';
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }

?>

Используйте Google File Picker для выбора файлов.

Для вашего варианта использования вам, вероятно, лучше использовать Google Picker https://developers.google.com/picker/docs/, который реализует всю вещь для поиска и выбора файлов для вас, и просто дает идентификатор файл. Краткое изложение необходимых шагов:

  1. Получить токен доступа (аутентификация)
  2. Используйте picker, чтобы пользователь мог выбрать файл
  3. Использовать идентификатор файла, возвращенный из сборщика, чтобы получить URL загрузки
  4. Загрузить файл из URL-адреса загрузки

Мы можем сделать это двумя способами (на стороне клиента или на стороне сервера):

Способ 1: Клиентская сторона

Используя этот метод, шаги 1 - 3 выполняются в Javascript, и только шаг 4 выполняется в PHP. С помощью этого метода нам даже не нужна клиентская библиотека PHP!

Вот пример (адаптированный из примера кода в приведенной выше ссылке и http://webdevrefinery.com/forums/topic/12931-dropbox-google-drive-file-pickers/):

picker.html

Этот файл запускает filepicker при загрузке страницы и помещает URL-адрес в форму.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>Google Picker Example</title>


        <script type="text/javascript">

            // The Browser API key obtained from the Google Developers Console.
            var developerKey = '';

            // The Client ID obtained from the Google Developers Console. Replace with your own Client ID.
            var clientId = ""

            // Replace with your own App ID. (Its the first number in your Client ID)
            var appId = ""

            // Scope to use to access user Drive items.
            var scope = ['https://www.googleapis.com/auth/drive'];

            var pickerApiLoaded = false;
            var oauthToken;

            // Use the Google API Loader script to load the google.picker script.
            function loadPicker() {
                gapi.load('auth', {'callback': onAuthApiLoad});
                gapi.load('picker', {'callback': onPickerApiLoad});
            }

            function onAuthApiLoad() {
                window.gapi.auth.authorize(
                {
                    'client_id': clientId,
                    'scope': scope,
                    'immediate': false
                },
                handleAuthResult);
            }

            function onPickerApiLoad() {
                pickerApiLoaded = true;
                createPicker();
            }

            function handleAuthResult(authResult) {
                if (authResult && !authResult.error) {
                    oauthToken = authResult.access_token;
                    createPicker();
                }
            }

            // Create and render a Picker object
            function createPicker() {
                if (pickerApiLoaded && oauthToken) {                
                    var view = new google.picker.DocsView();
                    view.setIncludeFolders(true);
                    //view.setMimeTypes("image/png,image/jpeg,image/jpg");

                    var picker = new google.picker.PickerBuilder()
                    //.enableFeature(google.picker.Feature.NAV_HIDDEN)
                    //.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
                    .setAppId(appId)
                    .setOAuthToken(oauthToken)
                    .addView(view)
                    .setDeveloperKey(developerKey)
                    .setCallback(pickerCallback)
                    .build();
                    picker.setVisible(true);
                }
            }

            // A simple callback implementation.
            function pickerCallback(data) {
                if (data.action == google.picker.Action.PICKED) {
                    var fileId = data.docs[0].id;

                    gapi.client.load('drive', 'v2', function() {
                        var request = gapi.client.drive.files.get({
                            fileId: fileId
                        });
                        request.execute(processFile);           
                    });

                }
            }

            function processFile(file) {
                var token = gapi.auth.getToken();
                // console.log(file);
                // console.log(token);
                document.getElementById("fileurl").value = file.downloadUrl+"&access_token="+token.access_token;
            }
        </script>
    </head>
    <body>
        <form action="submit.php" method="post">
            <label for="fileurl">File Download URL</label><input type="text" name="fileurl" id="fileurl">
            <input type="submit">
        </form>

        <!-- The Google API Loader script. -->
        <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
        <script type="text/javascript" src="https://apis.google.com/js/client.js"></script>
    </body>
</html>

Затем мы передаем форму скрипту PHP для загрузки файла на сервере. Хитрость здесь заключается в том, что нам также необходимо передать токен доступа от клиента к серверу, поскольку пользователь не аутентифицирован на стороне сервера. Удивительно, но вы можете просто добавить параметр access_token для аутентификации загрузки файла, как показано выше.

submit.php

Используйте file_get_contents или CURL, в зависимости от того, что поддерживает ваш сервер. Для этого требуется поддержка HTTPS.

<?php

    $filename = 'temp.jpg';

    $ch = curl_init($_POST['fileurl']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // Should verify in production!
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    $data = curl_exec($ch);
    //echo 'Curl error: ' . curl_error($ch);
    curl_close($ch);

    file_put_contents($filename, $data);

?>

Более официальным способом (следуя https://developers.google.com/drive/web/manage-downloads#alternate_method_using_downloadurl) является отправка маркера авторизации отдельно с использованием заголовка Authorization. Измените Javascript выше, чтобы отправить URL-адрес загрузки и токен отдельно, а затем используйте что-то вроде кода ниже. Если вы хотите использовать file_get_contents, см. PHP file_get_contents() и заголовки о том, как отправлять пользовательские заголовки. Обратите внимание, что перед маркером необходимо иметь слово- Bearer !

<?php

    $filename = 'temp.jpg';

    $ch = curl_init($_POST['fileurl']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$_POST['authtoken']));

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    $data = curl_exec($ch);
    echo 'Curl error: ' . curl_error($ch);
    curl_close($ch);

    file_put_contents($filename, $data);

?>

Способ 2. Сервер (с использованием PHP)

Используя этот метод, шаги 1, 3 и 4 выполняются в PHP, и только шаг 2 выполняется в Javascript.

quickstart.php

На этой странице проверяется наличие токена доступа в сеансе, если он не перенаправляет пользователя на аутентификацию. Если есть, то отображается сборщик и форма. Обратите внимание, что в коде Javascript, который используется oAuthToken, получается с PHP с сервера! Источник: используйте Google Picker без входа в аккаунт Google (с OAuth). Затем форма отправляет запрос POST на эту страницу, и файл загружается.

<?php
    require_once 'google-api-php-client/src/Google/autoload.php';

    session_start();

    // Ref: https://developers.google.com/drive/v2/reference/files/get
    function downloadFile($service, $file) {
        $downloadUrl = $file->getDownloadUrl();
        if ($downloadUrl) {
            $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
            $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
            if ($httpRequest->getResponseHttpCode() == 200) {
                return $httpRequest->getResponseBody();
                } else {
                // An error occurred.
                return null;
            }
            } else {
            // The file doesn't have any content stored on Drive.
            return null;
        }
    }

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json');
    $client->addScope(Google_Service_Drive::DRIVE_READONLY);

    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        $client->setAccessToken($_SESSION['access_token']);
        if (isset($_POST['fileid'])){           
            $drive_service = new Google_Service_Drive($client);
            $file = $drive_service->files->get($_POST['fileid']);
            $data = downloadFile($drive_service, $file);
            file_put_contents('temp.jpg', $data);

            echo "file uploaded";
            exit();
        }
    } else {
        $redirect_uri = 'http://localhost/drivepicker-php/oauth2callback.php';
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
        exit();
    }   

?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>Google Picker Example</title>


        <script type="text/javascript">

            // The Browser API key obtained from the Google Developers Console.
            var developerKey = '';

            // Replace with your own App ID. (Its the first number in your Client ID)
            var appId = ""

            var pickerApiLoaded = false;

            // Use the Google API Loader script to load the google.picker script.
            function loadPicker() {
                gapi.load('picker', {'callback': onPickerApiLoad});
            }

            function onPickerApiLoad() {
                pickerApiLoaded = true;
                createPicker();
            }

            // Create and render a Picker object
            function createPicker() {
                if (pickerApiLoaded) {              
                    var view = new google.picker.DocsView();
                    view.setIncludeFolders(true);
                    //view.setMimeTypes("image/png,image/jpeg,image/jpg");

                    var picker = new google.picker.PickerBuilder()
                    //.enableFeature(google.picker.Feature.NAV_HIDDEN)
                    //.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
                    .setAppId(appId)
                    .setOAuthToken('<?= json_decode($client->getAccessToken())->access_token; ?>')
                    .addView(view)
                    .setDeveloperKey(developerKey)
                    .setCallback(pickerCallback)
                    .build();
                    picker.setVisible(true);
                }
            }

            // A simple callback implementation.
            function pickerCallback(data) {
                if (data.action == google.picker.Action.PICKED) {
                    var fileId = data.docs[0].id;
                    document.getElementById("fileid").value = fileId;

                }
            }
        </script>
    </head>
    <body>
        <form action="quickstart.php" method="post">
            <label for="fileid">File ID</label><input type="text" name="fileid" id="fileid">
            <input type="submit">
        </form>

        <!-- The Google API Loader script. -->
        <script type="text/javascript" src="https://apis.google.com/js/api.js?onload=loadPicker"></script>
        <script type="text/javascript" src="https://apis.google.com/js/client.js"></script>
    </body>
</html>

oauth2callback.php

Вспомогательный файл для обратного вызова OAuth.

<?php
    require_once 'google-api-php-client/src/Google/autoload.php';

    session_start();

    $client = new Google_Client();
    $client->setAuthConfigFile('client_secrets.json');
    $client->setRedirectUri('http://localhost/drivepicker-php/oauth2callback.php');
    $client->addScope(Google_Service_Drive::DRIVE_READONLY);

    if (!isset($_GET['code'])) {
        $auth_url = $client->createAuthUrl();
        header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
    } else {
        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
        $redirect_uri = 'http://localhost/drivepicker-php/quickstart.php';
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
    }

?>
  • 0
    Большое спасибо за подробный ответ. Я сейчас дома, поэтому не смогу попробовать до завтра. У меня есть настройки моего проекта в консоли, но я не сталкивался с client_secrets.json, о котором вы упомянули - откуда мне его взять?
  • 0
    Вы можете получить client_secrets.json с console.developers.google.com (где вы получаете свои идентификаторы и секрет). Существует опция «Загрузить JSON» после создания идентификатора клиента. Он не будет называться client_secrets.json , но просто переименуйте его или измените значение переменной по client_secrets.json . Как примечание, этот файл json должен быть секретным и не должен находиться в каталоге, доступном через Интернет, в производственной среде.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню