用于存储和刷新 google oauth2 凭据的一些常见 Python 设计模式是什么

What are some of the common Python design patterns for storing and refreshing google oauth2 credentials

我正在构建我的第一个 Python 应用程序,正在寻求一些了解 google oauth 和相关应用程序设计模式的建议。我的主要目标是构建一个应用程序来轮询我的 Nest 以获取数据并学习如何安全地执行此操作。使用 google 的 API 和 oauth2 Python 库,我已经成功创建了一个微型 Flask 应用程序,它将 return 来自 google API 的数据] 连同身份验证令牌 + 刷新令牌。核心功能看起来像这样:

sdm = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

response = sdm.api.endpoint.call(API_PARAMS)

此应用使用 client_secret.json 创建 ouath ID 期间生成的信息。但是,在浏览 google 的文档和各种教程时,我得到的印象是我应该使用身份验证令牌(不记名令牌?)来进行这些 API 调用而不是 client_secrets.json

我最初的想法是构建一个使用 refresh_token 刷​​新 auth_token 并将其存储在某处的应用程序。然后我会有第二个应用程序读取 auth_token 并进行 API 调用、存储数据等。在尝试创建第一个获取和刷新身份验证令牌的应用程序时,我创建了一个两者兼顾的应用程序。

构建两个函数(轮询数据和身份验证)似乎是正确的方法。它允许我将令牌、刷新令牌和 client_secrets 分开并将它们保存在不同的地方,因为 API 轮询函数只需要知道身份验证令牌。

我的问题是,我在尝试将 auth_refresh 和 api_calls 分开以分离应用程序时是否过于复杂?安全存储和使用 oauth 凭证的最常用方法是什么?在哪里可以找到有关常见 google API + oauth 设计模式的更多信息?很可能我一次阅读了太多的教程,并且在 google 文档迷宫中融化了我的大脑。非常感谢。

在仔细阅读文档和 Whosebug 代码片段后,我使用 google API 和 oauth Python 库找到了下面的内容。分离这些职责似乎是正确的做法。理论上,您可以使用 curl 或 Python 请求库来完成相同的操作。这种方法对我来说似乎是“最干净的”。情人之眼等等...

无论如何,这里是需要在后端进程中独立轮换和使用 google api 身份验证令牌的核心部分(这里,具体来说,我想定期轮询我的 Nest 并存储数据)。它假定您已经处理了客户端授权请求并且 google 用户已经授权了该应用程序。此处概述的部分主要用于使用凭据post 授权。

import google.oauth2.credentials
import google.auth.transport.requests
import googleapiclient.discovery


# the first function refreshes the auth token every hour and writes it to secrets storage
# it can access the more sensitive bits like refresh_token
credentials = google.oauth2.credentials.Credentials(
            token=TOKEN
            refresh_token=REFRESH_TOKEN,
            token_uri=TOKEN_URI,
            client_id=CLIENT_ID,
            client_secret=CLIENT_SECRET
        )

# refresh the token
request = google.auth.transport.requests.Request()
credentials.refresh(request)
TOKEN = credentials.token

write_to_secrets_store(TOKEN)


# the second function does the API call and related stuffs
# it can see the token but none of the sensitive bits like refresh_token and client_secret
credentials = google.oauth2.credentials.Credentials(token=TOKEN)

# make an api call
sdm = googleapiclient.discovery.build(
            API_SERVICE_NAME, API_VERSION, credentials=credentials)

api_results = sdm.enterprises().structures().list(parent=ENTERPRISE_PARENT).execute()

do_stuff_with(api_results)