Authenticating with the Google Drive API using an indefinite refresh token
Wed, 23 January 2019
google-drive-access.php
//
// This redirect uri must be whitelisted and applied in the 'API' section of the Google Cloud Console.
// The full path to the resource is needed, not just the domain name.
//
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$credentials = '{"web":{"client_id":"zjztQk4qG4PbdP7VUAtUCwaXRi8OFnj2-YOnRUZiORF17v2D4ZFOpkFfFxo0CKJ1d.apps.googleusercontent.com","project_id":"my-google-project-id","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"vhyWj4h7ZLyqRnAkFVcPwqKwhFPHyU1c"}}';
$oauth_credentials = json_decode($credentials, true);
if (!$oauth_credentials) {
echo 'No oauth credentials';
exit;
}
$client = new Google_Client();
$client->setAuthConfig($oauth_credentials);
$client->setRedirectUri($redirect_uri);
$client->setAccessType("offline");
$client->setApprovalPrompt("force");
$client->addScope("https://www.googleapis.com/auth/drive");
$service = new Google_Service_Drive($client);
//
// Step 1
//
// If no refresh token, redirect to the Google auth page.
//
// 1) Check the database for a refresh token for this user, if we have one, check it works.
// 2) If it doesn't work, redirect the user to the auth url.
//
if (!isset($_GET['code']) && empty($_SESSION['refresh_token'])) {
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
exit;
}
//
// Step 2
//
// Retrieved initial code from Google to retrieve an access token. Access tokens only last 1 hour. Refresh tokens
// last indefinitely.
//
// 1) Get the access token.
// 2) Get the refresh token -> Store this in the database.
//
if (isset($_GET['code'])) {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
$client->setAccessToken($token);
$refreshToken = $client->getRefreshToken();
$_SESSION['refresh_token'] = $refreshToken; // or from a db
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
exit;
}
//
// Step 3
//
// We've got the refresh token, using that we can fetch an access token
// refresh tokens never expire - although they can be revoked by the user.
//
// 1) Fetch an access token using the refresh token (this access token changes every request then).
// 2) Using this new access token we have access to the Google Drive API
// 3) Create an example file.
//
if (!empty($_SESSION['refresh_token'])) {
$randomFileName = 'test-file' . uniqid() . '.txt';
$accessToken = $client->fetchAccessTokenWithRefreshToken($_SESSION['refresh_token']);
$file = new Google_Service_Drive_DriveFile();
$file->setName($randomFileName);
$result = $service->files->create(
$file,
array(
'data' => sprintf('This is a test file called %s', $randomFileName),
'mimeType' => 'text/plain',
'uploadType' => 'media'
)
);
echo '<h1>Create file result:</h1>';
echo sprintf(
'<a href="https://drive.google.com/open?id=%s" target="_blank">%s (File ID: %s)</a>',
$result->id,
$result->name,
$result->id
);
echo '<hr>';
echo '<h1>Access Token Data:</h1>';
var_dump($accessToken);
}