Ошибка разрешений учетной записи службы Google / файл не найден

#php #google-api #google-drive-api #google-api-php-client #google-api-client

#php #google-api #google-drive-api #google-api-php-client #google-api-client

Вопрос:

Я хочу отправить наши резервные копии MySQL с нашего веб-сервера на Google Диск, используя скрипт PHP и API Google Drive, который будет настроен как задание cron.

Я понимаю, что это приложение для обмена данными между серверами, поэтому для него требуется учетная запись службы Google (я знаю, что это может быть возможно с учетной записью пользователя и обновлением токена доступа — но я не думаю, что это правильный вариант использования, поскольку я бы хотел практически не взаимодействовать с пользователем?).

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

 function getClient()
{
    $client = new Google_Client();

    if ($credentials_file = checkServiceAccountCredentialsFile()) 
    {
        // set the location manually
        $client->setAuthConfig($credentials_file);
    }
    else 
    {
        echo missingServiceAccountDetailsWarning();
        return;
    }

    $client->setApplicationName('Backups');
    $client->setScopes(Google_Service_Drive::DRIVE);

    $guzzleClient = new GuzzleHttpClient(array( 'curl' => array( CURLOPT_SSL_VERIFYPEER => false, ), ));
    $client->setHttpClient($guzzleClient);

    return $client;
}
  
 $file_to_upload = 'test.txt';

if(file_exists($file_to_upload))
{
    // Get the API client and construct the service object.
    $client = getClient();

    $service = new Google_Service_Drive($client);

    $folder_id = '#####################-##########';

    $file = new Google_Service_Drive_DriveFile();
    $file->setName($file_to_upload);
    $file->setParents(array($folder_id));

    $result = $service->files->create(
      $file,
      array(
        'data' => file_get_contents("test.txt"),
        'mimeType' => 'text/plain',
        'uploadType' => 'multipart'
      )
    );
}
  

Это возвращает следующее исключение:

 Fatal error: Uncaught Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "notFound", "message": "File not found: #####################-##########.", "locationType": "parameter", "location": "fileId" } ], "code": 404, "message": "File not found: #####################-##########." } }
  

Я понимаю, что это ошибка разрешений — идентификатор папки правильный и соответствует каталогу, который был предоставлен совместно с учетной записью службы:

  1. Я не добавил идентификатор клиента учетной записи службы и https://www.googleapis.com/auth/drive доступ к консоли администратора GSuite — это обязательный шаг, который я пропустил? (В настоящее время у меня нет доступа к консоли администратора).

  2. Я заметил, что учетные записи служб доступны для обычных учетных записей, отличных от GSuite, так как же это будет работать, если они не смогут добавить область действия?

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

  4. Существуют ли какие-либо другие ранее существовавшие решения, которые могут создавать резервные копии файлов с веб-сервера на Google Диск?

Ответ №1:

Об ошибке разрешения:

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

  • Поскольку папка не расположена на личном диске учетной записи службы, вам необходимо установить параметр supportsAllDrives true — см. Документацию для файлов: Создать.

  • В противном случае папка не может быть найдена, что приводит к полученному вами сообщению об ошибке.

О авторизации областей в консоли администратора:

  • Этот шаг необходим только тогда, когда вы используете делегирование по всему домену, то есть если вы позволяете учетной записи службы представлять другого пользователя (например, вас) и действовать от его имени.

  • Имейте в виду, что использование олицетворения в масштабе домена невозможно для учетной записи, отличной от G Suite (теперь называемой Google Workspace), поэтому этим пользователям не нужно авторизовывать соответствующие области в консоли администратора.

  • Для использования учетных записей служб без делегирования домена (как в вашем случае) вам нужно только включить соответствующий API (Drive) для соответствующего проекта GCP и включить область действия в свой код.

  • Имейте в виду, что ваша ошибка была вызвана проблемами с разрешениями, вы, вероятно, получили бы код ошибки 403 вместо 404.

Комментарии:

1. Спасибо — оказывается, мы не можем совместно использовать какие-либо каталоги за пределами нашей организации. Прав ли я, полагая, что делегирование по всему домену все еще можно использовать, поскольку учетная запись службы тогда фактически будет находиться в организации, ИЛИ другим вариантом будет заставить учетную запись службы создать каталог и поделиться им с организацией?

2. Если у вас есть организация, вы правы, полагая, что вы можете использовать делегирование в масштабах всего домена для обезличивания пользователей вашего домена Google Work Space, но не пользователей за пределами домена.

3. Спасибо, я попробую делегировать домен. Если скрипт будет выполняться на нескольких серверах (я хочу отправить резервные копии каждого сервера на диск), нужен ли каждому серверу собственный ключ API или все они могут использовать один и тот же ключ?

4. Я думаю, если у вас не возникнут проблемы с квотами, я думаю, вы можете использовать те же учетные данные (учетная запись службы, а не ключи API в вашем случае).