Автоматически обновлять токен с помощью API Google Диска с PHP скриптом

Я снова выполнил ЭТО РУКОВОДСТВО, чтобы загрузить файл на Google Диск с php, прямо из моего УДАЛЕННОГО СЕРВЕРА: поэтому я создал новый проект API из консоли Google API, включил службу Drive API, запросил идентификатор клиента OAuth и секрет клиента, написал их в скрипте, а затем загрузил его вместе с Папка клиентской библиотеки API Google для PHP в эту http://www.MYSERVER.com/script1.php, чтобы получить код аутентификации:

<?php

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

$drive = new Google_Client();

$drive->setClientId('XXX'); // HERE I WRITE MY Client ID

$drive->setClientSecret('XXX'); // HERE I WRITE MY Client Secret

$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');

$drive->setScopes(array('https://www.googleapis.com/auth/drive'));

$gdrive = new Google_DriveService($drive);

$url = $drive->createAuthUrl();
$authorizationCode = trim(fgets(STDIN));

$token = $drive->authenticate($authorizationCode);

?>

Когда я посещаю http://www.MYSERVER.com/script1.php, я разрешаю авторизация и получите код аутентификации, который я могу написать во втором скрипте. Затем я загружаю его на http://www.MYSERVER.com/script2.php, который смотрит нравиться:

<?php

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

$drive = new Google_Client();

$drive->setClientId('X');  // HERE I WRITE MY Client ID
$drive->setClientSecret('X');  // HERE I WRITE MY Client Secret
$drive->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
$drive->setScopes(array('https://www.googleapis.com/auth/drive'));

$gdrive = new Google_DriveService($drive);

$_GET['code']= 'X/XXX'; // HERE I WRITE AUTH CODE RETRIEVED AFTER RUNNING REMOTE script.php

file_put_contents('token.json', $drive->authenticate());

$drive->setAccessToken(file_get_contents('token.json'));

$doc = new Google_DriveFile();

$doc->setTitle('Test Drive');
$doc->setDescription('Document');
$doc->setMimeType('text/plain');

$content = file_get_contents('drive.txt');

$output = $gdrive->files->insert($doc, array(
      'data' => $content,
      'mimeType' => 'text/plain',
    ));

print_r($output);

?>

Что ж, теперь файл drive.txt загружен на мой Google Диск, а структура файла token.json выглядит примерно так:

{"access_token":"XXX","token_type":"Bearer","expires_in":3600,"refresh_token":"YYY","created":1365505148}

Теперь, как вы понимаете, я могу вызвать script2.php и загрузить файл до определенного времени. Наконец, суть в следующем: я не хочу, чтобы срок действия токена истекал, я не хочу разрешать авторизацию каждый раз, когда он истекает (вспоминая script1.php): I нужно периодически вызывать script2.php в течение дня, чтобы загружать мой файл автоматически, без взаимодействия с пользователем. Итак, как лучше всего автоматически обновить токен навсегда в этом контексте? Мне нужен другой сценарий? Могу я добавить код в script2.php? или изменить файл token.json? И где я могу прочитать время, оставшееся до истечения срока действия токена? Спасибо!


person Huxley    schedule 09.04.2013    source источник


Ответы (2)


Вам не нужно периодически запрашивать токен доступа. Если у вас есть refresh_token, клиент PHP автоматически получит для вас новый токен доступа.

Чтобы получить refresh_token, вам необходимо установить для access_type значение «offline» и запросить разрешения на доступ в автономном режиме:

$drive->setAccessType('offline');

Как только вы получите code,

$_GET['code']= 'X/XXX';
$drive->authenticate();

// persist refresh token encrypted
$refreshToken = $drive->getAccessToken()["refreshToken"];

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

$tokens = $drive->getAccessToken();
$tokens["refreshToken"] = $refreshToken;
$drive->setAccessToken(tokens);

Если вы хотите обновить токен принудительного доступа, вы можете сделать это, вызвав refreshToken:

$drive->refreshToken($refreshToken);

Осторожно, refresh_token будет возвращен только на первом $drive->authenticate(), вам нужно его постоянно хранить. Чтобы получить новый refresh_token, вам необходимо отозвать существующий токен и снова запустить процесс аутентификации.

Автономный доступ подробно описан в документации Google OAuth 2.0.

person Burcu Dogan    schedule 09.04.2013
comment
Спасибо, @Burcu, суть в ваших словах. Если срок действия вашего токена доступа истек: КОГДА Я МОГУ ПРОСМОТРЕТЬ, что срок действия моего токена доступа истек? это постоянно или нет? - person Huxley; 09.04.2013
comment
@ Хаксли, он выдаст Google_AuthException. С другой стороны, эта клиентская библиотека автоматически обновляет токен доступа, если истекает срок действия текущего. Итак, обычно вы никогда не увидите ошибку авторизации. Я редактирую свой ответ выше. - person Burcu Dogan; 09.04.2013
comment
Я получил refresh_token и access_token из консоли OAuth 2.0 Playground и сохранил их в моем файле token.json: это одно и то же? они постоянные? - person Huxley; 09.04.2013
comment
@Huxley, вы не можете использовать refresh_token, полученный OAuth 2.0 Playground, вам нужно получить токены с вашим собственным идентификатором клиента и секретом клиента. В противном случае PHP lib не сможет обновить токен доступа. / * Автономный доступ предоставляется OAuth 2.0 Playground, а не вашему приложению. * / - person Burcu Dogan; 09.04.2013
comment
Что ж, @Burcu, но если вы видите мой вопрос в файле token.json, я УЖЕ обновил и получил токен доступа после первой аутентификации и первого вызова script2.php, на самом деле я могу идеально загрузить файлы: Я все еще нужно получить другие токены? Спасибо за ваше терпение :) - person Huxley; 09.04.2013
comment
@Huxley, как только вы получите их, как в своем примере, вы можете сохранить их и использовать где угодно, вам больше не нужно попадать в какой-либо другой поток аутентификации. Жетоны обновления никогда не истекают, к вашему сведению. - person Burcu Dogan; 09.04.2013
comment
Отлично, @Burcu, я был немного сбит с толку, потому что после моего примера (script2.php) вы ответили ДРУГОЙ способ получить токен обновления, поэтому я подумал, что мой был неправильным, и ваш был ЕДИНСТВЕННЫМ способом! После первой аутентификации я сохранил токены, поэтому теперь я использую небольшую вариацию script2.php, и, как писал вы, клиент PHP автоматически получит новый токен доступа. Еще раз спасибо! - person Huxley; 10.04.2013
comment
Пожалуйста, измените $ drive- ›setAccessToken (токены); to $ drive- ›setAccessToken ($ tokens); Думаю, это опечатка (Надеюсь, между мирами Java и PHP, да?;))! - person Eswar Rajesh Pinapala; 17.02.2014
comment
Чувак, спасибо, мне помогла строчка о том, что токен обновления был возвращен только ПЕРВЫЙ раз авторизации. - person Stormsson; 07.10.2014

После того, как я много возился, я заставил это работать. Я использую один файл / скрипт для получения автономного токена, а затем класс для работы с api:

require_once 'src/Google/autoload.php'; // load library

session_start();

$client = new Google_Client();
// Get your credentials from the console
$client->setApplicationName("Get Token");
$client->setClientId('...');
$client->setClientSecret('...');
$client->setRedirectUri('...'); // self redirect
$client->setScopes(array('https://www.googleapis.com/auth/drive.file'));
$client->setAccessType("offline");
$client->setApprovalPrompt('force'); 



if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    $client->getAccessToken(["refreshToken"]);
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
    return;
}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

if (isset($_REQUEST['logout'])) {
    unset($_SESSION['token']);
    $client->revokeToken();
}


?>
<!doctype html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
        <header><h1>Get Token</h1></header>
        <?php
        if ($client->getAccessToken()) {
            $_SESSION['token'] = $client->getAccessToken();
            $token = json_decode($_SESSION['token']);
            echo "Access Token = " . $token->access_token . '<br/>';
            echo "Refresh Token = " . $token->refresh_token . '<br/>';
            echo "Token type = " . $token->token_type . '<br/>';
            echo "Expires in = " . $token->expires_in . '<br/>';
            echo "Created = " . $token->created . '<br/>';
            echo "<a class='logout' href='?logout'>Logout</a>";
            file_put_contents("token.txt",$token->refresh_token); // saving access token to file for future use
        } else {
            $authUrl = $client->createAuthUrl();
            print "<a class='login' href='$authUrl'>Connect Me!</a>";
        }
        ?>
    </body>
</html>

Вы можете загрузить токен обновления из файла и использовать его по мере необходимости для автономного доступа:

class gdrive{

function __construct(){
        require_once 'src/Google/autoload.php';
        $this->client = new Google_Client();
}

function initialize(){
        echo "initializing class\n";
        $client = $this->client;
        // credentials from google console
        $client->setClientId('...');
        $client->setClientSecret('...');
        $client->setRedirectUri('...');

        $refreshToken = file_get_contents(__DIR__ . "/token.txt"); // load previously saved token
        $client->refreshToken($refreshToken);
        $tokens = $client->getAccessToken();
        $client->setAccessToken($tokens);

        $this->doSomething(); // go do something with the api       
    }
}

Подробнее здесь: https://github.com/yannisg/Google-Drive-Uploader-PHP < / а>

person Yannis Giovanos    schedule 06.08.2015