繁体   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