谷歌云盘API、Oauth和服务账号

53

我在使用Google Drive API、服务帐户和身份验证方面遇到了一些问题。我阅读了很多资料,但是仍然无法解决这个问题。

背景:我在我的Drive帐户上有一些文件(约35GB),还有一个简单的Web应用程序,让用户登录,查看我Drive中选择的某些文件夹/文件,并在需要时下载它们。唯一可以直接访问我的Drive帐户的人(或应该是)是我的服务器,用户通过Web应用程序/服务器执行其操作。

经过一番搜索,我发现服务器对服务器授权文档非常适合我的目的,但是,据我所知,服务帐户不共享相同的Drive空间:它们有自己的空间,而且不能升级。由于这个(奇怪的)限制,我不能使用服务帐户,因为我有超过35GB的数据需要“共享”。

其他方法:使用“标准”OAuth以获取访问令牌,然后使用它调用Drive API,但是访问令牌会过期,我无法手动更新每个令牌。

那么,第一个问题:有没有办法增加服务帐户的配额?如果没有,是否有一种方法可以使用我的“正常”帐户(所有者)代替服务帐户?

第二个(虚拟的)问题:我阅读了创建新的OAuth凭据的文档,最后你会得到一个示例代码和“客户端密钥”JSON。我运行了这个示例,但我不明白那个JSON文件的作用是什么:我必须登录并授权,为什么我还需要它?

第三个(足够虚拟的)问题:如果OAuth是唯一的解决方案,是否有一种方法可以在不手动进行的情况下获得/刷新访问令牌?我查看了OAuth文档,“用户交互/确认”是认证流程中的基本事项之一,因此我认为这是不可能的。


1
请参见以下链接:https://dev59.com/AWIj5IYBdhLWcg3w6JHU - pinoyyid
太棒了!我之前没发现这个,我会试一下这种方法,看看会发生什么...非常感谢! - user6208310
2个回答

136

将您的Drive帐户文件夹共享给您的服务帐户。
您的服务帐户地址看起来像XXX@XXX.iam.gserviceaccount.com。
然后您的服务帐户就可以从您的Drive帐户中查看共享的文件夹。
因此,您有35GB的服务帐户。


11
这这这!!!!哇。我在 Stackoverflow 上挣扎了很多篇文章...... 直到看到这一篇。你救了我!非常感谢 @drinkmystery。我欠你一个人情。 - pmalbu
4
这个答案真的帮了我很多。我之前非常讨厌谷歌云盘,因为它让我的生活变得很糟糕。 - David Olmo Pérez
3
这是正确的答案! - Irvin Chan
2
谢谢您的见解。这非常有帮助,因为快速入门页面没有提到这种方法,至少我没有注意到。 - Kota Mori
1
我可以确认,到今天为止,这仍然有效...我也曾经苦恼于此,非常感谢!!! - KurroGB
显示剩余5条评论

13

如果您的帐户是私人帐户而不是Google Workspace(以前称为G Suite)的一部分,则drinkmystery的答案 是正确的方法。否则,有一种更简洁的方法可以使用createDelegated() 方法来解决这个问题。此处有详细描述,并且您应该按照那里的所有配置说明进行操作,但是提供的代码示例基于一些已弃用的软件包,因此我花了一些时间将其与Drive API教程中的代码样本结合起来使其正常工作。

因此,对于只需要一个工作代码示例的人,这是它(请注意使用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'
}


感谢您提供使用服务账户的示例。 - Welington Veiga
请查看以下链接:https://console.developers.google.com/apis/credentials/wizard 和 https://chrisboakes.com/building-a-rest-api-with-google-sheets-and-aws-lambda/。 - David
我收到了POST https://oauth2.googleapis.com/token { "error": "invalid_grant", "error_description": "无效的电子邮件或用户ID" } - Psijic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接