简体   繁体   English

Google Drive API、Oauth 和服务帐户

[英]Google Drive API, Oauth and service account

I've some issues with Google Drive API, service account and authentication.我在 Google Drive API、服务帐户和身份验证方面遇到了一些问题。 I read a lot, but I cannot figure out how to solve this.我读了很多,但我不知道如何解决这个问题。

Context: I have some files on my Drive account (about 35GB) and a simple web app which let users to log in, see some selected folders/files from my Drive and download them if needed.上下文:我的 Drive 帐户中有一些文件(大约 35GB)和一个简单的 Web 应用程序,可让用户登录,查看我的 Drive 中的一些选定文件夹/文件,并在需要时下载它们。 The only one who can directly access to my Drive account is (or should be) my server, users do their stuff through web app/server.唯一可以直接访问我的 Drive 帐户的是(或应该是)我的服务器,用户通过网络应用程序/服务器做他们的事情。

After some search I found server-to-server authorization docs that should be perfect for my purpose BUT, as I can see, service account does not share same Drive space: they have their own and it's not upgradable.经过一番搜索,我发现服务器到服务器的授权文档应该非常适合我的目的,但是,正如我所看到的,服务帐户不共享相同的驱动器空间:它们有自己的并且不可升级。 Because of this (weird) limit I cannot use service account since I have more than 35GB and I need to "share" everything.由于这个(奇怪的)限制,我无法使用服务帐户,因为我有超过 35GB 的空间,我需要“共享”所有内容。

Other way: use "standard" OAuth in order to obtain an access token and then use it to make call to Drive API, but access tokens have an expire date and I can't update it manually every time.其他方式:使用“标准”OAuth 来获取访问令牌,然后使用它来调用 Drive API,但访问令牌有一个过期日期,我不能每次都手动更新它。

So, first question: is there a way to increase quota for service account?那么,第一个问题:有没有办法增加服务帐户的配额? If not, if there a way to use my "normal" account (owner) acting like a service account?如果没有,是否有办法像服务帐户一样使用我的“普通”帐户(所有者)?

Second (dummy) question: I read docs about creating new OAuth credentials and at the end you obtain some example code and "client-secret" JSON.第二个(虚拟)问题:我阅读了有关创建新 OAuth 凭据的文档,最后您获得了一些示例代码和“客户端机密”JSON。 I run the example but I didn't understand what the role of that JSON file is: I must log in and give permission anyway, why do I need it?我运行了这个例子,但我不明白那个 JSON 文件的作用是什么:我必须登录并授予权限,为什么我需要它?

Third (dummy enough) question: if OAuth is the only solution, is there a way to obtain/refresh access tokens without doing it manually every time?第三个(足够愚蠢的)问题:如果 OAuth 是唯一的解决方案,有没有办法获取/刷新访问令牌而无需每次都手动执行? I looked at OAuth docs and "user interaction/confirmation" is one of the basic thing in the auth flow, so I don't think is possible.我查看了 OAuth 文档,“用户交互/确认”是身份验证流程中的基本内容之一,所以我认为这是不可能的。

Share your Drive account's folder to your service account.将您的云端硬盘帐户的文件夹共享到您的服务帐户。
Your service account's addresss looks like XXX@XXX.iam.gserviceaccount.com.您的服务帐号的地址类似于 XXX@XXX.iam.gserviceaccount.com。
Then your service account can see the shared folder from your Drive account.然后您的服务帐户可以从您的云端硬盘帐户看到共享文件夹。
So you have 35GB service account.所以你有 35GB 的服务帐户。

The answer of drinkmystery is the right way to go in case your account is private and not a part of Google Workspace (formerly GSuite).如果您的帐户是私人帐户而不是 Google Workspace(以前称为 GSuite)的一部分,那么 Drinkmystery的答案是正确的方法。 Otherwise, there's a more elegant way to solve this with the createDelegated() method.否则,有一种更优雅的方法可以使用createDelegated()方法解决此问题。 It was described here and you should follow all the configuration instructions from there, but the code samples provided there are based on some deprecated packages, so it took me some time to make it work properly combining with the codes from the Drive API tutorial .它在此处进行了描述,您应该遵循那里的所有配置说明,但是那里提供的代码示例基于一些已弃用的软件包,因此我花了一些时间与Drive API 教程中的代码相结合才能使其正常工作。

So for those who just need a working code sample, here it is (note the use of createDelegated ):所以对于那些只需要一个工作代码示例的人来说,这里是(注意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());
            }
        }
    }
}

Please, make sure your project dependencies are up to date (don't use blindly those from the Drive API tutorial).请确保您的项目依赖项是最新的(不要盲目使用 Drive API 教程中的那些)。 Here is my build.gradle:这是我的 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'
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM