使用 Python 和 Google Drive API 防止 Google API 令牌过期?

Preventing Google API token expiry using Python and Google Drive API?

我有下面的示例代码,它试图访问我个人 Google 云端硬盘帐户中的文件。早期版本有一个烦人的问题,即 Google 每次 运行 都需要通过在浏览器中打开 link 来手动启用它。这就是为什么我通过包含 Oauth2 来修改代码并相信它会永远解决这个问题。但是今天,我再次发现以下控制台消息:

File "c:\...\site-packages\oauth2client\client.py", line 819, in _do_refresh_request
    raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.

我认为下面代码中 if not credentials 条件的目的是专门根据 client_secrets 文件自动更新凭据,从而防止此类手动启用。

完整代码如下:

from googleapiclient.discovery import build
from oauth2client import client, tools 
from oauth2client.file import Storage

api_client_secret = r"C:\...\client_secret_0123456789-abc123def456ghi789.apps.googleusercontent.com.json"
credential_file_path = r"C:\...\credential_sample.json"

class GoogleDriveAccess:

    def __init__(self):
        self.service = self.get_authenticated_service(api_client_secret, credential_file_path, 'drive', 'v3', ['https://www.googleapis.com/auth/drive'])

    def get_authenticated_service(self, client_secret_file_path, credential_file_path, api_name, api_version, scopes):
        store = Storage(credential_file_path)
        credentials = store.get()
        if not credentials or credentials.invalid:
            flow = client.flow_from_clientsecrets(client_secret_file_path, scopes)
            credentials = tools.run_flow(flow, store)
        return build(api_name, api_version, credentials=credentials)

if __name__ == '__main__':
    GoogleDriveAccess()

我在这里错过了什么?我如何确保 Google 不会自动撤销我对自己的 Google 帐户的访问权限?

处于测试阶段的应用程序的刷新令牌将在 7 天后过期。

Refresh token expiration

A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.

将您的应用程序投入生产,它不会过期

或考虑切换到 service account

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

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