Issues with Downloading Files Using PHP Google Drive API

I am experiencing difficulties when trying to download files from Google Drive through the PHP API. Although the upload process to a particular folder is successful, accessing the downloadUrl from the returned file resource results in a 401 unauthorized error. The upload is successful, and I receive the file object, but the download URL does not work. Has anyone encountered a similar issue? What could I be overlooking in this process?

<?php
require_once 'vendor/autoload.php';
session_start();

$client_id = 'xxx';
$client_secret = 'yyy';
$redirect_uri = 'http://localhost/DriveTest/code.php';

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/drive");

$service = new Google_Service_Drive($client);

$authUrl = $client->createAuthUrl();
header("Location: $authUrl");
?>

And in code.php:

<?php
require_once 'vendor/autoload.php';
session_start();

$client_id = 'xxx';
$client_secret = 'yyy';
$redirect_uri = 'http://localhost/DriveTest/redirect.php';

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setApprovalPrompt('force');
$client->addScope("https://www.googleapis.com/auth/drive");

$service = new Google_Service_Drive($client);

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

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    $client->setAccessToken($_SESSION['access_token']);
    if ($client->isAccessTokenExpired()) {
        unset($_SESSION['access_token']);
    }
}

if ($client->getAccessToken()) {
    $fileObject = new Google_Service_Drive_DriveFile();
    $fileObject->setTitle("sample_file.exe");
    $fileObject->setDescription("Sample file upload");
    $fileObject->setMimeType('application/x-msdos-program');

    $parentReference = new Google_Service_Drive_ParentReference();
    $parentReference->setId("folder_id");
    $fileObject->setParents(array($parentReference));

    $fileContent = file_get_contents('sample_file.exe');
    $uploadedFile = $service->files->insert($fileObject, array(
            'data' => $fileContent,
            'mimeType' => 'application/x-msdos-program',
            'uploadType' => 'multipart',
            'visibility' => 'DEFAULT'
    ));

    header("Location: " . $uploadedFile->downloadUrl);
}
?>

Hey Alice, heads up - you’re using old v2 API methods like setTitle() and downloadUrl. Those are deprecated now. Switch to v3: use setName() instead, and for downloads call $service->files->get($fileId, array('alt' => 'media')) directly. The downloadUrl property doesn’t work in newer versions.

Check your redirect URI - you’ve got a mismatch. Your first file sets redirect_uri to ‘code.php’ but code.php uses ‘redirect.php’. This inconsistency will cause auth issues and 401 errors down the line. Both files need to use the exact same redirect URI that matches what’s in your Google Console. Also, your session might be dropping the token between requests. Add some debug output to check if $_SESSION[‘access_token’] actually has a valid token before you try downloading anything.

The 401 error occurs because the downloadUrl requires authentication headers that are not included in the redirect response. I faced this same issue previously. Instead of redirecting to the downloadUrl, you should perform an authenticated HTTP request with your access token using cURL. Include the Authorization header with your bearer token and then stream the response. Additionally, verify that your token hasn’t expired, as this is often the cause of 401 errors, even if other parts of the code appear correct.