【问题标题】:Automatically refresh token using google drive api with php script使用带有 php 脚本的 google drive api 自动刷新令牌
【发布时间】:2013-04-01 01:40:38
【问题描述】:

我再次关注THIS TUTORIAL,直接从我的远程服务器使用 php 在 Google Drive 上上传文件:所以我从 Google API 控制台创建了新的 API 项目,启用 Drive API 服务,请求 OAuth 客户端 ID 和客户端密码,将它们写在脚本中,然后将其与Google APIs Client Library for PHP文件夹一起上传到这个http://www.MYSERVER.com/script1.php,以检索Auth code:

<?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 时,我允许授权 并获得我可以在第二个脚本中编写的 Auth 代码。然后我上传到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 Drive 上,并且 token.json 文件的结构是这样的:

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

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

【问题讨论】:

    标签: php google-api google-drive-api google-api-php-client


    【解决方案1】:

    您不必定期请求访问令牌。如果你有一个 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-&gt;authenticate() 上返回,您需要永久存储它。为了获得新的 refresh_token,您需要撤销现有的令牌并重新启动身份验证过程。

    离线访问在Google's OAuth 2.0 documentation有详细说明。

    【讨论】:

    • 谢谢@Burcu,重点在于“如果您的访问令牌已过期”:我何时可以看到我的访问令牌已过期?它是永久性的吗?
    • @Huxley,它会抛出一个Google_AuthException。另一方面,如果当前的访问令牌即将过期,此客户端库会自动刷新访问令牌。因此,通常您永远不会看到身份验证错误。我正在编辑上面的答案。
    • 我已经从 OAuth 2.0 Playground 控制台检索了 refresh_token 和 access_token 并将其存储在我的 token.json 文件中:它是一回事吗?它们是永久性的吗?
    • @Huxley,您不能使用由 OAuth 2.0 Playground 检索到的 refresh_token,您需要使用您自己的客户端 ID 和客户端密码检索令牌。否则,PHP lib 将无法刷新访问令牌。 /* 离线访问权限授予 OAuth 2.0 Playground,而不是您的应用。 */
    • 好吧,@Burcu,但是如果您在 token.json 文件中看到我的问题,我已经刷新并在第一次身份验证和第一次调用 script2.php 后检索到访问令牌,事实上我可以完美上传文件:我还需要检索其他令牌吗?谢谢你的耐心:)
    【解决方案2】:

    在搞砸了很多之后,我得到了这个工作。我正在使用一个文件/脚本来获取离线令牌,然后使用一个类来使用 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

    【讨论】:

      猜你喜欢
      • 2017-10-10
      • 2019-02-16
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 2018-02-06
      相关资源
      最近更新 更多