Youtube Data API v.3 - 全自动 oAuth 流程(Python)?

Posted

技术标签:

【中文标题】Youtube Data API v.3 - 全自动 oAuth 流程(Python)?【英文标题】:Youtube Data API v.3 - fully automated oAuth flow (Python)? 【发布时间】:2020-01-24 03:41:55 【问题描述】:

我一直在探索 YouTube 数据 API。我的项目的前提很简单:使用 API,进行身份验证(是的,我有帐户的凭据),然后简单地检索我的所有公开和私人视频的列表。

除了完全自动化的部分外,我已经能够成功地完成这项工作。我使用了各种来源的代码,当我在命令行上运行它时,它为我提供了一个在浏览器中使用的链接,以便进行授权。

看起来像这样:

请访问此 URL 以授权此应用程序:https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=7932902759886-cb8ai84grcqshe24nn459ka46uh45ssj.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&state=zNVvgEyO47nmacvdEEAhDsQipY194k&prompt=consent&access_type=offline&code_challenge=aF7uTCghjwgwjg49o3fgiIU-_ryK19rDeX4l1uzr37w&code_challenge_method=S256 输入授权码:

....

这是我的 python 代码的 sn-p:

import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
...
...

# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
    client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(
    api_service_name, api_version, credentials=credentials)
## MAKE youtube SEARCH REQUEST
last_date = '2018-10-01T00:00:00Z'
request = youtube.search().list(
    part="snippet",
    forMine=True,
    maxResults=50,
    order="date",
    type="video"
)
all_items = []
response = request.execute()

我的问题如下:是否可以以编程方式执行授权,以便应用程序可以独立运行而不必等待此用户操作(从 CMD 复制 URL,访问以获取令牌,然后再次复制并粘贴令牌)?我想安排这个,因此希望它在没有人工干预的情况下运行和验证。这可能吗?如果是这样,有人可以指点我一些工作示例和/或其他资源来帮助我实现目标吗?谢谢一百万。

【问题讨论】:

【参考方案1】:
# -*- coding: utf-8 -*-
# Sample Python code for youtube.channels.list
# See instructions for running these code samples locally:
# https://developers.google.com/explorer-help/guides/code_samples#python
#!/usr/bin/python3.7
import os
import pickle
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
client_secrets_file = "client_secret.json"
api_service_name = "youtube"
api_version = "v3"

def main():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    # Get credentials and create an API client
    flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
        client_secrets_file, scopes)
    youtube = get_authenticated_service()
    request = youtube.channels().list(
        part="contentDetails",
        mine=True
    )
    response = request.execute()
    print(response)

def get_authenticated_service():
    if os.path.exists("CREDENTIALS_PICKLE_FILE"):
        with open("CREDENTIALS_PICKLE_FILE", 'rb') as f:
            credentials = pickle.load(f)
    else:
        flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(client_secrets_file, scopes)
        credentials = flow.run_console()
        with open("CREDENTIALS_PICKLE_FILE", 'wb') as f:
            pickle.dump(credentials, f)
    return googleapiclient.discovery.build(
        api_service_name, api_version, credentials=credentials)
if __name__ == "__main__":
    main()

【讨论】:

【参考方案2】:

来自credentials = flow.run_console()Credentials 实例具有刷新令牌的内置功能。 如果需要,它将在执行请求时刷新令牌。

因此您可以将credentials 对象保存到pickle 中,并在需要时读取它

对 Google python 示例代码的一些改动:

def get_authenticated_service():
    if os.path.exists(CREDENTIALS_PICKLE_FILE):
        with open(CREDENTIALS_PICKLE_FILE, 'rb') as f:
            credentials = pickle.load(f)
    else:
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
        credentials = flow.run_console()
        with open(CREDENTIALS_PICKLE_FILE, 'wb') as f:
            pickle.dump(credentials, f)
    return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)

【讨论】:

【参考方案3】:

复制自https://developers.google.com/identity/protocols/OAuth2InstalledApp

第 3 步:Google 提示用户同意 在此步骤中,用户决定是否授予您的应用程序请求的访问权限。在此阶段,Google 会显示一个同意窗口,其中显示您的应用程序的名称以及它正在请求使用用户授权凭据访问权限的 Google API 服务。然后,用户可以同意或拒绝授予对您的应用程序的访问权限。

您的应用程序在此阶段不需要执行任何操作,因为它会等待来自 Google 的 OAuth 2.0 服务器的响应,指示是否已授予访问权限。该响应将在以下步骤中解释。

这很重要:

在此阶段,Google 会显示一个同意窗口,其中显示您的应用程序的名称以及它正在请求使用用户授权凭据访问权限的 Google API 服务。

因此,至少按照我的解释,出于安全原因,您不应该做您想做的事情。 但是:您可以通过 python 有多少库来“模拟”浏览器。另一方面:一旦你获得了 auth-token,你就可以重复使用它,而不是每次都请求一个新的 token。我在 GitHub 上提供的文档中找不到它,但作为示例的 Java 支持将获得的令牌与其刷新令牌一起存储,因此一旦获得并自动刷新就可以重用它。也许python提供了一些方法来存储获得的令牌(检查它是否包含刷新令牌)并重新加载它。另外:如果你加载这样的令牌,首先你要做的是在使用它之前刷新它。 Java 提供了一种只保存刷新令牌而不是整个 auth-token 的方法,可以在以后的运行中使用它来自动获取新的 auth-token。 由于响应是 JSON,如果 lib 尚未提供此功能,您可以自己构建一些。

// 编辑

另外来自https://github.com/googleapis/google-auth-library-python/blob/master/google/oauth2/credentials.py 有一些方法可以从“授权用户信息”(我也在某处发现可以从文件加载)或直接从文件加载凭据对象。所以,我想你只需要弄清楚如何存储令牌。正如文档对 from_authorized_user_file 所说:

从授权用户 json 文件创建一个 Credentials 实例。

我想这意味着您只需保存在初始授权完成后获得的令牌响应。

【讨论】:

以上是关于Youtube Data API v.3 - 全自动 oAuth 流程(Python)?的主要内容,如果未能解决你的问题,请参考以下文章

Youtube API v3 data.search 返回相同的值

使用 YouTube Data API v3 确定 YouTube 频道的上传速率

Youtube [Data-API] LiveChat,登录用户为版主

使用 Youtube Data API V3 和 Google API Client PHP 将视频上传到 Youtube - 获取 401(未经授权)消息

Youtube Data API V3 - 使用google.youtube.videos.list()获取视频时出错

Youtube Data API V3 - 使用 google.youtube.videos.list() 获取视频时出错