簡體   English   中英

如何使用 Google Drive API 通過服務帳戶訪問域中的共享文件?

[英]How to get access to shared files in a domain with a service account using the Google Drive API?

我一直在嘗試從 Python 3.7 腳本訪問有關 Google Shared Drive 文件的一些簡單信息:

上次修改共享驅動器上的 Google 表格文件的時間。

我在 GCP Drive API 菜單中創建了一個服務帳戶,它可以通過 Sheets API 毫無問題地訪問/編輯/等 Google Sheets。

但是,當我為 Drive API 使用相同的服務帳戶時,它不會返回有關其自己文件夾(僅包含一個文件:“入門”)之外的文件的任何信息。 該帳戶可以訪問所有 Cloud API,具有域范圍的委派,其中包含與 GSuite 的 API 控制菜單中包含的 Drive API 相關的所有范圍。

服務帳戶的電子郵件地址已正確添加到共享驅動器中的所有文件夾。

任何的想法? 基本上我只需要知道任何給定用戶最后一次修改工作表是什么時候。

secret_cred_file = ...
SCOPES = ['https://www.googleapis.com/auth/drive']
credentials = service_account.Credentials.from_service_account_file(secret_cred_file, scopes=SCOPES)
service = discovery.build('drive', 'v3', credentials=credentials)
results = service.files().list(pageSize=10, fields="nextPageToken, files(id, name,modifiedTime)").execute()
items = results.get('files', [])

PS:我見過這個: 從共享文件夾中獲取文件但它沒有幫助

您需要模擬您的用戶。

不可能通過調用 API 一次性獲取域中的所有文件。

服務帳戶文章中,它說:

與用戶帳戶不同,服務帳戶不是您的 Google Workspace 域的成員。 例如,如果您與 Google Workspace 網域中的所有成員共享資產,它們將不會與服務帳號共享...這在使用域范圍委派時不適用,因為 API 調用被授權為模擬用戶,而不是服務帳戶本身。

所以很遺憾,您不能只與服務帳戶共享文件。 要獲取域中的所有文件,您需要:

  1. 模擬管理員帳戶並獲取所有用戶的列表。
  2. 模擬每個用戶並為每個用戶發出 Drive API 請求。

這是Python 庫的一個很好的快速入門,特別是本節

請記住在 GCP 控制台和管理控制台中設置權限,盡管您似乎已正確完成此操作。

示例腳本

from google.oauth2 import service_account
from googleapiclient.discovery import build

def main():

    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
        'https://www.googleapis.com/auth/admin.directory.user.readonly']
    SERVICE_ACCOUNT_FILE = 'credentials.json'

    credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    # Admin SDK to get users
    admin_delegated_credentials = credentials.with_subject('[ADMIN_EMAIL]')
    admin_service = build(
        'admin',
        'directory_v1',
        credentials=admin_delegated_credentials
        )

    admin_results = admin_service.users().list(customer='my_customer', maxResults=10,
                                orderBy='email').execute()
    users = admin_results.get('users', [])

    if not users:
        print('No users in the domain.')
    else:
        for user in users:
            print(u'{0} ({1})'.format(user['primaryEmail'],
                user['name']['fullName']))

            # Drive to get files for each user
            delegated_credentials = credentials.with_subject(user['primaryEmail'])

            drive_service = build(
                'drive',
                'v3',
                credentials=delegated_credentials
                )
            drive_results = drive_service.files().list(
                pageSize=10,
                fields="nextPageToken, files(id, name,modifiedTime)"
                ).execute()
            items = drive_results.get('files', [])

            if not items:
                print('No files found.')
            else:
                print('Files:')
                for item in items:
                    print(u'{0} ({1})'.format(item['name'],
                        item['id']))

if __name__ == '__main__':
    main()

解釋

這個腳本有兩個作用域:

  • 'https://www.googleapis.com/auth/drive.metadata.readonly'
  • 'https://www.googleapis.com/auth/admin.directory.user.readonly'

在 GCP Cloud 控制台中初始化的項目也已從管理控制台 > 安全 > API 控制 > 域范圍委派 > 添加新的

腳本所做的第一件事是使用from_service_account_file構建憑據:

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

然后它構建委托憑據,即要模擬的用戶:

admin_delegated_credentials = credentials.with_subject('[ADMIN_EMAIL]')

從那里它可以正常構建服務。 它獲取用戶列表,遍歷用戶並列出他們的文件。 您可以根據自己的需要進行調整。

參考

我能夠通過向google 文檔中所述的 list 方法添加一些參數來列出共享驅動器文件,而無需冒充用戶:

實施共享驅動器支持

共享雲端硬盤遵循與“我的雲端硬盤”不同的組織、共享和所有權模式。 如果您的應用要在共享驅動器上創建和管理文件,您必須在應用中實現共享驅動器支持。 首先,當您的應用程序執行這些操作時,您需要在請求中包含supportsAllDrives=true查詢參數:

files.get、files.list、files.create、files.update、files.copy、files.delete、changes.list、changes.getStartPageToken、permissions.list、permissions.get、permissions.create、permissions.update、權限。刪除

搜索共享雲端硬盤上的內容

使用 files.list 方法搜索共享驅動器。 本節介紹 files.list 方法中的共享驅動器特定字段。 要搜索共享驅動器,請參閱搜索文件和文件夾。

files.list 方法包含以下共享驅動器特定字段和查詢模式:

driveId — 要搜索的共享驅動器的 ID。

includeItemsFromAllDrives — 共享驅動器項目是否應包含在結果中。 如果不存在或設置為 false,則不會返回共享驅動器項目。

corpora — 查詢適用的項目(文件/文檔)的主體 支持的主體是用戶、域、驅動器和所有驅動器。 為了效率,用戶或驅動器優先於所有驅動器。

supportAllDrives — 請求應用程序是否同時支持我的驅動器和共享驅動器。 如果為 false,則響應中不包含共享驅動器項目。

例子

service.files().list(includeItemsFromAllDrives=True, supportsAllDrives=True, pageSize=10, fields="nextPageToken, files(id, name,modifiedTime)").execute()

很高興記住文件夾或文件需要與服務帳戶共享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM