【发布时间】:2024-01-23 20:03:01
【问题描述】:
我编写了一个脚本,它将在我们公司的多个用户 gdrive 中搜索文件。问题是该脚本可以工作,但只能运行一段时间,但随后会出现 HTTP 401 错误,这很可能是由于访问令牌过期。我正在使用启用了域范围委派的服务帐户,并使用 google.oauth2 python 库来创建 Drive 服务对象(参见下面的代码)。我想以编程方式获取刷新令牌并在当前令牌过期时生成新的访问令牌。问题是没有关于如何使用服务帐户执行此操作的文档。有正常的用户交互 oauth 流程。我的问题是如何使用驱动器对象来检索刷新令牌,然后创建新的访问令牌。我知道我将不得不以某种方式使用我的服务帐户的私钥,但不确定。
我一直在阅读这两个文档。 https://developers.google.com/identity/protocols/oauth2 https://developers.google.com/identity/protocols/oauth2/service-account
- 使用模拟用户创建驱动服务对象
from google.oauth2 import service_account
import googleapiclient.discovery
def impersonate_user(user_to_impersonate, key_file, domain):
scopes = ['https://www.googleapis.com/auth/drive',]
if user_to_impersonate is None:
raise InvalidDomainUser(f"{user_to_impersonate} is not a member of {domain}")
if key_file is None:
raise FileNotFoundError(f"{key_file} is not a valid service account file")
delegated_credentials = service_account.Credentials.from_service_account_file(
key_file, scopes=scopes)
# Impersonate User.
delegated_credentials = delegated_credentials.with_subject(user_to_impersonate)
drive_service = googleapiclient.discovery.build('drive', 'v2', credentials=delegated_credentials)
# Set new drive resource object
return drive_service
- 列出用户驱动器中的文件
service = impersonate_user(user_to_impersonate, key_file, domain):
children = service.children().list(folderId=folderId,maxResults=1000, **param).execute()
for child in items:
item = service.files().get(fileId=child['id']).execute()
print(item.get("title", None))
【问题讨论】:
-
当您说“脚本有效但仅在一段时间内”时,具体需要多少时间?创建服务后,您是否只使用一次列表?还是在很长一段时间后再次使用相同的服务对象?
-
嘿,它会在大约 1 小时后过期。 3600 秒。之后,每个 api 调用都会导致 401 错误。我在一段时间内使用相同的驱动器对象,除非该用户驱动器中的文件或文件夹归其他人所有,在这种情况下,我将通过模拟新用户来重新实例化该对象
-
为什么不在每次需要时(延长时间后)创建一个新的服务对象?
-
另外,请确保
user_to_impersonate始终是来自与服务帐户相同的域的用户。您可能会传递一个空值。但实际上您的情况听起来像是尽管创建了服务帐户凭据,但您的代码使用访问令牌而不是创建服务对象。 -
嘿,我现在开始工作了。这是我的代码中的逻辑错误。但它现在似乎正在工作。感谢您的帮助!
标签: python google-drive-api google-oauth google-admin-sdk google-api-python-client