Google Drive API、Oauth 和服务帐号
Posted
技术标签:
【中文标题】Google Drive API、Oauth 和服务帐号【英文标题】:Google Drive API, Oauth and service account 【发布时间】:2018-01-11 13:26:33 【问题描述】:我在 Google Drive API、服务帐户和身份验证方面遇到了一些问题。我读了很多,但我不知道如何解决这个问题。
上下文:我的云端硬盘帐户中有一些文件(大约 35GB)和一个简单的网络应用程序,用户可以登录,查看我的云端硬盘中的一些选定文件夹/文件,并在需要时下载它们。 唯一可以直接访问我的云端硬盘帐户的是(或应该是)我的服务器,用户通过网络应用程序/服务器完成他们的工作。
经过一番搜索,我发现 server-to-server authorization docs 应该非常适合我的目的,但是,正如我所见,服务帐户不共享相同的云端硬盘空间:他们有自己的空间,而且不可升级。由于这个(奇怪的)限制,我无法使用服务帐户,因为我有超过 35GB 的空间,我需要“共享”所有内容。
其他方式:使用“标准”OAuth 来获取访问令牌,然后使用它来调用 Drive API,但访问令牌有一个过期日期,我不能每次都手动更新它。
那么,第一个问题:有没有办法增加服务帐户的配额?如果没有,是否有办法像服务帐户一样使用我的“普通”帐户(所有者)?
第二个(虚拟)问题:我阅读了有关creating new OAuth credentials 的文档,最后您获得了一些示例代码和“客户端机密”JSON。我运行了这个例子,但我不明白那个 JSON 文件的作用是什么:无论如何我必须登录并授予权限,我为什么需要它?
第三个(足够愚蠢的)问题:如果 OAuth 是唯一的解决方案,有没有一种方法可以获取/刷新访问令牌,而无需每次都手动进行?我查看了 OAuth 文档,“用户交互/确认”是身份验证流程中的基本内容之一,所以我认为这是不可能的。
【问题讨论】:
见***.com/questions/19766912/… 太棒了!之前没找到,我就这样试试,看看会发生什么……非常感谢! 【参考方案1】:将您的云端硬盘帐户的文件夹共享到您的服务帐户。 您的服务帐号的地址类似于 XXX@XXX.iam.gserviceaccount.com。 然后,您的服务帐户可以查看您云端硬盘帐户中的共享文件夹。 所以你有 35GB 的服务帐户。
【讨论】:
这这这这!!!!!!哇。我在很多 *** 帖子中都苦苦挣扎……直到这一篇。你救了我!非常感谢@drinkmystery。我很感激你。 这个答案对我很有帮助。我非常讨厌 Google 云端硬盘让我的生活变得悲惨 实现此共享需要多长时间才能显示在服务帐户中.. 这是正确的答案!! 感谢您的洞察力。这很有帮助,因为快速入门页面没有提到这种方法,至少据我所知。【参考方案2】:drinkmystery 的答案是正确的方法,以防您的帐户是私人帐户而不是 Google Workspace(以前的 GSuite)的一部分。否则,使用createDelegated()
方法可以更优雅地解决此问题。它被描述为here,您应该按照那里的所有配置说明进行操作,但是那里提供的代码示例基于一些已弃用的包,所以我花了一些时间使其与Drive API tutorial 中的代码结合使用才能正常工作.
所以对于那些只需要一个工作代码示例的人来说,这里是(注意使用createDelegated
):
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.ServiceAccountCredentials;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
public class DelegatedDriveWithServiceAccountQuickstart
private static final String APPLICATION_NAME = "your awesome app";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
private static final String CREDENTIALS_FILE_PATH = "/path/to/your/service-account-key-downloaded-from-google-api-console.json";
public static void main(String... args) throws IOException, GeneralSecurityException
// Build a new authorized API client service
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(ServiceAccountCredentials.fromStream(new FileInputStream(CREDENTIALS_FILE_PATH))
.createScoped(SCOPES)
.createDelegated("user.whose.drive.you.want.to.share@your-domain-in-gsuite.com"));
Drive driveService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
.setApplicationName(APPLICATION_NAME)
.build();
// Print the names and IDs for up to 10 files.
FileList result = driveService.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<File> files = result.getFiles();
if (files == null || files.isEmpty())
System.out.println("No files found.");
else
System.out.println("Files:");
for (File file : files)
System.out.printf("%s (%s)\n", file.getName(), file.getId());
请确保您的项目依赖项是最新的(不要盲目使用 Drive API 教程中的那些)。这是我的 build.gradle:
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'DelegatedDriveWithServiceAccountQuickstart'
sourceCompatibility = 1.8
targetCompatibility = 1.8
version = '1.0'
repositories
mavenCentral()
dependencies
compile 'com.google.api-client:google-api-client:1.31.1'
compile 'com.google.apis:google-api-services-drive:v3-rev20201130-1.31.0'
compile 'com.google.auth:google-auth-library-oauth2-http:0.22.2'
【讨论】:
感谢您提供使用服务帐户的示例。以上是关于Google Drive API、Oauth 和服务帐号的主要内容,如果未能解决你的问题,请参考以下文章
Google Drive API Python 服务帐户示例
具有多个用户帐户的Google Drive SDK OAuth2
Google Drive API 推送通知订阅 400“解析错误”
尝试使用 Google Drive API 的错误 JWT 签名