使用 Google 表格 / Google 云端硬盘 API 请求特定文件权限更新 2020

我正在使用Google Sheets API来获取Java项目的工作表数据。所有这些都在本地按预期工作,但我使用的是详细的权限范围 https://www.googleapis.com/auth/spreadsheets“允许对用户的工作表及其属性进行读/写访问”。我宁愿不向此应用提供对 Google 云端硬盘中所有电子表格的访问权限(仅在本地临时执行此操作)。

理想情况下,我想使用文件的ID请求对文件的读/写访问权限。这可能吗?

如果不可能,我猜 https://www.googleapis.com/auth/drive.file 范围提供“对应用程序创建或打开的文件的按文件访问”是我能得到的最接近的。我还没有设法找到一种方法来打开这个应用程序的文件。我该怎么做呢?

或者,如果上述两种解决方案都不理想或不可能,请告诉我您的建议。

谢谢!


答案 1

我知道这是很久以前发布的,但我会给出我的答案,以帮助未来的开发人员将来遇到这个问题。

我认为使用服务帐户将为您提供在此处查找的功能。服务帐户有点像用户可以与之共享文档的“机器人”用户,然后您的服务器可以登录到此服务帐户以访问这些文档。您不必请求访问用户的整个Google云端硬盘或Google工作表,您可以让他们手动与您共享文档,我认为这对大多数用户来说会更舒适。

下面是一个如何在 Node 中设置它的示例.js,但这些想法应该很容易地转换为 Java。


答案 2

作用域授予你跨 API 的访问权限,无法将其限制为单个文件或文件组。

Google Sheets API, v4 Scopes

无法将权限限制为单个文件。假设您正在编辑的文件是由应用程序创建的,那么应该是一个有效的选项https://www.googleapis.com/auth/drive.file

样本

Java 快速入门

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
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.client.util.store.FileDataStoreFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.ValueRange;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

public class SheetsQuickstart {
    private static final String APPLICATION_NAME = "Google Sheets API Java Quickstart";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";

    /**
     * Global instance of the scopes required by this quickstart.
     * If modifying these scopes, delete your previously saved tokens/ folder.
     */
    private static final List<String> SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

    /**
     * Creates an authorized Credential object.
     * @param HTTP_TRANSPORT The network HTTP Transport.
     * @return An authorized Credential object.
     * @throws IOException If the credentials.json file cannot be found.
     */
    private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
        // Load client secrets.
        InputStream in = SheetsQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build();
        LocalServerReceiver receier = new LocalServerReceiver.Builder().setPort(8888).build();
        return new AuthorizationCodeInstalledApp(flow, receier).authorize("user");
    }

    /**
     * Prints the names and majors of students in a sample spreadsheet:
     * https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
     */
    public static void main(String... args) throws IOException, GeneralSecurityException {
        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        final String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
        final String range = "Class Data!A2:E";
        Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();
        ValueRange response = service.spreadsheets().values()
                .get(spreadsheetId, range)
                .execute();
        List<List<Object>> values = response.getValues();
        if (values == null || values.isEmpty()) {
            System.out.println("No data found.");
        } else {
            System.out.println("Name, Major");
            for (List row : values) {
                // Print columns A and E, which correspond to indices 0 and 4.
                System.out.printf("%s, %s\n", row.get(0), row.get(4));
            }
        }
    }
}

更新 2020

有一种方法可以授予每个文件的访问权限。

https://www.googleapis.com/auth/drive.file对应用创建或打开的文件的按文件访问权限。文件授权基于每个用户授予,并在用户取消对应用取消授权时撤消。


推荐