当前位置: 首页 > 知识库问答 >
问题:

谷歌驱动器访问令牌自动化

仰翰采
2023-03-14

这段代码对我来说很好,但在可能24小时后,我需要再次进行身份验证过程。我希望这个认证过程只做一次,因为在我的项目中,他们将没有人参与,所以没有人会手动进行认证。任何帮助都将不胜感激。

"refreshtoken.php"
<?php
require __DIR__ . '/vendor/autoload.php'; // load library

session_start();

$client = new Google_Client();
// Get your credentials from the console
    $client->setApplicationName('Google Drive API PHP Quickstart');
    $client->setRedirectUri('http://localhost/query.php');

    $client->setScopes(Google_Service_Drive::DRIVE);
    $client->setAuthConfig('credentials.json');
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');



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 id ='connect' class='login' href='$authUrl'>Connect Me!</a>";
        }
        ?>
    </body>
</html>
"callback.php"
<?php
        require __DIR__ . '/vendor/autoload.php';
        
        function url_origin( $s, $use_forwarded_host = false )
        {
            $ssl      = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' );
            $sp       = strtolower( $s['SERVER_PROTOCOL'] );
            $protocol = substr( $sp, 0, strpos( $sp, '/' ) ) . ( ( $ssl ) ? 's' : '' );
            $port     = $s['SERVER_PORT'];
            $port     = ( ( ! $ssl && $port=='80' ) || ( $ssl && $port=='443' ) ) ? '' : ':'.$port;
            $host     = ( $use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ) ) ? $s['HTTP_X_FORWARDED_HOST'] : ( isset( $s['HTTP_HOST'] ) ? $s['HTTP_HOST'] : null );
            $host     = isset( $host ) ? $host : $s['SERVER_NAME'] . $port;
            return $protocol . '://' . $host;
        }

        function full_url( $s, $use_forwarded_host = false )
        {
            return url_origin( $s, $use_forwarded_host ) . $s['REQUEST_URI'];
        }
        function GetBetween($content,$start,$end)
{
            $r = explode($start, $content);
            if (isset($r[1])){
                $r = explode($end, $r[1]);
                return $r[0];
            }
            return '';
        }
        
        $absolute_url = full_url( $_SERVER );
        $code=GetBetween($absolute_url,'code=','&');
        echo "Authentication code: ".$code;
    
        $client = new Google_Client();
        $client->setApplicationName('Google Drive API PHP Quickstart');
        $client->setRedirectUri('http://localhost/query.php');

        $client->setScopes(Google_Service_Drive::DRIVE);
        $client->setAuthConfig('credentials.json');
        $client->setAccessType('offline');
        $client->setPrompt('select_account consent');
        
        $tokenPath = 'token.json';
        
        $authCode = $code;

        // Exchange authorization code for an access token.
         $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
         $client->setAccessToken($accessToken);
            
        if (!file_exists(dirname($tokenPath))) {
            mkdir(dirname($tokenPath), 0700, true);
        }
        file_put_contents($tokenPath, json_encode($client->getAccessToken()));

?>

共有1个答案

鲁展
2023-03-14

我的评论和Senthil的答案已经包含了所需的代码,但OP似乎仍然混乱,所以我将写一个答案来解释核心概念。

Google Drive API是一个通过OAuth进行身份验证的API。https://en.wikipedia.org/wiki/oauth

简单地说,它是一种机制,允许客户端应用程序(您的程序/代码)访问/使用存在于Google服务器(资源服务器和授权服务器)中的用户(资源所有者的)资源(他的Google Drive存储空间)。

  • 将用户重定向到Google的oauth授权endpoint
  • 从Google的oauth接收重定向,授权码在url参数中(授权码=一个使用码,短寿命)
  • 与刷新令牌交换授权代码(刷新令牌=可以多次使用,寿命长)
  • 与访问令牌交换刷新令牌(访问令牌=用于执行API调用/访问用户资源,使用时间短)
  • 使用需要访问令牌的API

上面说刷新令牌是长期存在的,但是到底有多长时间呢?这实际上取决于oauth协议的具体实现,但对于谷歌的oauth,我在4年前就问过一个问题:谷歌oauth2刷新令牌何时到期?并且,在写入此答案之前,当时(4年前)生成的刷新令牌尚未过期。我确保定期使用刷新令牌(至少每月使用一次cron)。另外,如果用户手动撤销了您的刷新令牌(撤销对应用程序的访问),您的刷新令牌将失效。

流程如下:

    null
$refresh_token = $client->getRefreshToken();
file_put_contents("/home/myusername/refresh_token.txt", $refresh_token);
    null
$refresh_token = your_method_to_load_refresh_token($username);
// e.g.: 
// $refresh_token = file_get_contents("/home/myusername/refresh_token.txt");
$client->fetchAccessTokenWithRefreshToken($refresh_token);
$client->some_method_to_upload_file($file);
 类似资料:
  • 难以理解oauth2令牌和刷新令牌进程 我有这个代码 上面的代码给了我一个访问令牌,我遵循了stackoverflower的同事pinoyyid建议的链接,但是,我对如何正确使用生成的访问令牌访问驱动器和复制文件感到困惑。。。 我看到的所有过程通常都涉及到,我不确定如何使用整个帖子http://.....事情,所以基本上我需要弄清楚,如果我在谷歌客户端的一个新实例中使用上面的代码获得的访问令牌,或

  • 我正在写一个Android(版本ICS)应用程序。它将数据上传到谷歌驱动器。应用程序使用oauth2获取访问令牌。 第一步:获取授权令牌。

  • 我已经完成了授权步骤,并获得了访问令牌和刷新令牌。

  • 在我的Java/Ionic2应用程序中,我通过REST服务请求使用刷新令牌对Google Drive进行身份验证,然后使用access_type=offline,如下所述:https://developers.Google.com/identity/protocols/oauth2webserver#refresh。 服务器响应200 OK,所以它给我一个刷新和一个访问令牌,只是在我第一次请求访问

  • 问题内容: 我将Google云端硬盘集成到我的应用中。并且希望每当连接的驱动器帐户中发生任何更改时都接收推送通知/ webhooks。自连接驱动器帐户一小时后,access_token过期,此后我无法收到任何Webhook。如何刷新并自动刷新? 问题答案: 您可以使用刷新令牌。可以通过刷新令牌来更新访问令牌。可以按以下方式检索此刷新令牌。首先,需要以下信息来检索refreshtoken。 客户编号

  • 下面是https://github.com/google/google-api-nodejs-client的代码。 一般问题:刷新令牌实际上如何与访问令牌一起工作? 背景:根据我的解释,每个访问令牌都有一个有限的时间跨度(~1小时)。因此,当用户第一次连接到我的服务器(服务器为用户身份验证提供了机制)时,服务器将收到有限生命期访问令牌和一次性刷新令牌。1小时后,访问令牌过期。 谢了!