使用带有php脚本的google drive api自动刷新令牌

使用带有php脚本的google drive api自动刷新令牌,php,google-api,google-drive-api,google-api-php-client,Php,Google Api,Google Drive Api,Google Api Php Client,我再次使用php在Google Drive上直接从远程服务器上传了一个文件:因此我从Google API控制台创建了一个新的API项目,启用了驱动器API服务,请求OAuth客户端ID和客户端密码,将其写入脚本,然后将其与文件夹一起上传到此,以检索身份验证代码: <?php require_once 'google-api-php-client/src/Google_Client.php'; require_once 'google-api-php-client/src/contrib/

我再次使用php在Google Drive上直接从远程服务器上传了一个文件:因此我从Google API控制台创建了一个新的API项目,启用了驱动器API服务,请求OAuth客户端ID和客户端密码,将其写入脚本,然后将其与文件夹一起上传到此,以检索身份验证代码:

<?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);

?>

现在,正如您所想象的,我可以调用script2.php并将文件上传到某个时间。最后,重点是:我不想令牌过期,我不想授权每次过期(回想script1.php):我需要在白天定期调用script2.php,自动上传我的文件,无需用户交互。那么,在此上下文中,自动永远刷新令牌的最佳方式是什么?我需要另一个脚本吗?我可以给script2.php添加一些代码吗?或者修改token.json文件?我在哪里可以读取令牌到期前的剩余时间?谢谢

您不必定期请求访问令牌。如果您有一个刷新令牌,PHP客户端将自动为您获取一个新的访问令牌

要检索刷新令牌,您需要将访问类型设置为“脱机”,并请求脱机访问权限:

$drive->setAccessType('offline');
一旦你得到一个
代码

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

// persist refresh token encrypted
$refreshToken = $drive->getAccessToken()["refreshToken"];
对于将来的请求,请确保始终设置刷新的令牌:

$tokens = $drive->getAccessToken();
$tokens["refreshToken"] = $refreshToken;
$drive->setAccessToken(tokens);
如果需要强制访问令牌刷新,可以通过调用
refreshttoken

$drive->refreshToken($refreshToken);
注意,
刷新\u令牌
将仅在第一个
$drive->authenticate()
上返回,您需要永久存储它。为了获得新的刷新令牌,您需要撤销现有令牌并再次启动身份验证过程


离线访问在上有详细的解释。

在做了很多事情之后,我让它工作起来。我使用一个文件/脚本获取脱机令牌,然后使用一个类来处理api:


更多信息:

Thank you@Burcu,关键在于您的话“如果您的访问令牌已过期”:我什么时候可以看到我的访问令牌已过期?它是永久的还是永久的?@Huxley,它会抛出一个
Google\u AuthException
。另一方面,如果当前的访问令牌即将过期,此客户端库将自动刷新访问令牌。因此,通常情况下,您永远不会看到身份验证错误。我正在编辑上面的答案。我已从OAuth 2.0游乐场控制台检索到refresh_token和access_token,并将其存储在我的token.json文件中:这是相同的吗?它们是永久的吗?@Huxley,你不能使用OAuth 2.0游乐场检索到的刷新令牌,你需要用你自己的客户端id和客户端密码检索令牌。否则,PHP库将无法刷新访问令牌。/*离线访问权限授予OAuth 2.0游乐场,而不是您的应用程序*/嗯,@Burcu,但是如果你在token.json文件中看到我的问题,我已经刷新并访问了在第一次身份验证和第一次调用script2.php之后检索到的令牌,事实上我可以完美地上传这些文件:我还需要检索其他令牌吗?谢谢你的耐心:)
$tokens = $drive->getAccessToken();
$tokens["refreshToken"] = $refreshToken;
$drive->setAccessToken(tokens);
$drive->refreshToken($refreshToken);
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       
    }
}