使用服务账户调用Google Drive API下载文件时跳转至登录页问题
Google服务账户PHP脚本下载跳登录页问题解决
问题描述
我通过Google服务账户实现了文件上传与下载的PHP脚本,此前运行正常,但目前下载功能异常:点击文件下载链接时并未开始下载,而是跳转至Google Drive登录页面。我未修改过PHP代码或Google Cloud配置,且已检查过两者未发现异常。目前上传功能正常,仅下载时会跳转至登录页。
相关代码如下:
require_once 'google-api-php-client/vendor/autoload.php'; putenv('GOOGLE_APPLICATION_CREDENTIALS=googlecredentials-path-file.json'); $client = new Google_Client(); $client->useApplicationDefaultCredentials(); $client->setScopes(['https://www.googleapis.com/auth/drive.file']); try { $service = new Google_Service_Drive($client); $google_file = new Google_Service_Drive_DriveFile(); $file_path = 'buho.jpg'; $google_file->setName($file_path); $google_file->setParents(['Google-Drive-folder-id']); $google_file->setDescription('File uploaded from a PHP application'); $google_file->setMimeType('image/jpeg'); $result = $service->files->create( $google_file, array( 'data' => file_get_contents($file_path), 'mimeType' => 'image/jpeg', 'uploadType' => 'media' ) ); echo '<a href="https://drive.google.com/open?id=' . $result->id . '" target="_blank">' . $result->name .'</a>'; } catch (Exception $e) { echo '上传失败:' . $e->getMessage(); }
原因分析
服务账户上传的文件默认仅对该服务账户本身开放权限,直接使用https://drive.google.com/open?id=文件ID这种公共链接时,普通访问者没有权限查看文件,因此会被引导至Google登录页面验证身份。
解决方法
方案1:修改文件权限为公开可访问
在文件上传完成后,添加权限配置代码,允许任何人以只读权限访问文件(支持下载):
// 在上传完成的$result之后添加以下代码 $permission = new Google_Service_Drive_Permission(); $permission->setType('anyone'); $permission->setRole('reader'); $service->permissions->create($result->id, $permission);
修改后,原有的Google Drive链接即可直接被访问并触发下载。
方案2:通过PHP API转发文件内容(更安全)
不直接跳转至Google Drive链接,而是通过PHP脚本借助服务账户权限获取文件内容,再设置响应头让浏览器直接下载:
- 替换原有的链接输出代码:
// 替换原echo链接的代码 echo '<a href="?download_id=' . $result->id . '" target="_blank">' . $result->name . '</a>';
- 在脚本开头添加下载请求处理逻辑:
require_once 'google-api-php-client/vendor/autoload.php'; putenv('GOOGLE_APPLICATION_CREDENTIALS=googlecredentials-path-file.json'); $client = new Google_Client(); $client->useApplicationDefaultCredentials(); $client->setScopes(['https://www.googleapis.com/auth/drive.file']); // 处理下载请求 if (isset($_GET['download_id'])) { $service = new Google_Service_Drive($client); $fileId = $_GET['download_id']; try { // 获取文件内容 $file = $service->files->get($fileId, ['alt' => 'media']); // 设置下载响应头 header('Content-Type: ' . $file->getHeaders()['Content-Type'][0]); header('Content-Disposition: attachment; filename="' . $result->name . '"'); echo $file->getBody(); exit; } catch (Exception $e) { echo '下载失败:' . $e->getMessage(); exit; } } // 原有的上传代码...
这种方式无需开放文件公共权限,通过服务账户的权限安全转发文件内容给用户。
内容的提问来源于stack exchange,提问作者Adn Officium
相关产品推荐
相关产品推荐

