PHP通过service account实现免登上传文件到Google Drive
基于Service Account实现访客无登录上传文件到个人Google Drive方案
你现有代码使用的是面向个人用户的OAuth授权流程,必须用户登录Google账号完成授权跳转才能获取访问凭证,和服务账号的服务器端免交互授权逻辑完全不匹配,所以无法实现需求。按以下步骤调整即可正常运行:
前置配置
- 在Google Cloud控制台启用Google Drive API,创建服务账号,下载服务账号对应的JSON密钥文件(注意不要下载成OAuth客户端密钥,两者格式和用途完全不同)
- 打开你个人Google Drive中用于存储上传文件的目标文件夹,将服务账号邮箱(JSON密钥内
client_email字段对应的邮箱地址)添加为文件夹协作者,授予编辑权限。服务账号自带独立的Drive存储空间,跳过这步的话上传的文件会存在服务账号的独立空间中,你的个人账号无法查看 - 从目标文件夹的URL中提取文件夹ID,后续代码中需要用到
代码调整
删除原有代码中所有和用户授权跳转、session存储token、生成授权链接相关的逻辑,服务账号不需要用户交互,后端直接通过密钥就能完成鉴权。对接HTML表单上传的完整可运行代码如下:
<?php // 引入Google Client依赖,composer安装的直接加载autoload即可 require __DIR__ . '/vendor/autoload.php'; $client = new Google\Client(); // 加载服务账号密钥文件,注意密钥不要放在web可直接访问的目录下,避免泄露 $client->setAuthConfig('service_account_credentials.json'); $client->addScope(Google\Service\Drive::DRIVE); $driveService = new Google\Service\Drive($client); // 处理表单提交 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['user_upload'])) { $file = $_FILES['user_upload']; if ($file['error'] !== UPLOAD_ERR_OK) { exit("文件上传出错,错误码:" . $file['error']); } // 配置上传文件元信息 $driveFile = new Google\Service\Drive\DriveFile(); $driveFile->setName($file['name']); // 上传后保留用户原文件名 $driveFile->setParents(['替换成你之前拿到的目标文件夹ID']); // 指定上传到你个人Drive的对应文件夹 // 执行上传 $uploadResult = $driveService->files->create( $driveFile, [ 'data' => file_get_contents($file['tmp_name']), 'mimeType' => mime_content_type($file['tmp_name']), 'uploadType' => 'multipart', 'fields' => 'id,webViewLink' ] ); // 按需设置文件权限,以下代码是给文件开所有人可读的链接权限,不需要可以删除 $permission = new Google\Service\Drive\Permission(); $permission->setType('anyone'); $permission->setRole('reader'); $driveService->permissions->create($uploadResult->id, $permission); echo "上传成功,文件访问地址:" . $uploadResult->webViewLink; exit; } ?> <!-- 访客可直接提交的上传表单,不需要登录Google账号 --> <form method="POST" enctype="multipart/form-data"> <input type="file" name="user_upload" required> <button type="submit">上传文件</button> </form>
注意事项
- 服务账号密钥必须放在web根目录外的非公开路径,一旦泄露他人可随意操作你的Drive文件
- 单文件超过5MB建议改用Google提供的分片上传接口,避免PHP内存溢出、请求超时
- 务必给目标文件夹添加服务账号编辑权限,否则会返回403权限错误
- 生产环境记得添加上传校验逻辑:包括文件大小限制、格式白名单、接口限流,避免被恶意上传占满存储空间
内容的提问来源于stack exchange,提问作者David Xoma
相关产品推荐
相关产品推荐

