使用 google 流程 2.0 时无法将用户重定向到 auth_uri

Unable to redirect the user to auth_uri while using google flow 2.0

我正在开发一个使用 YouTube 分析提取 YouTube 指标的应用程序 API。这是我第一次使用 google 身份验证流程来验证我的应用程序,以便它可以静默提取报告。

我正在关注下面 Google 发表的文章以得出相同的结果: https://developers.google.com/youtube/reporting/guides/authorization/server-side-web-apps

在阅读本文时,我无法弄清楚如何将用户重定向到 auth_uri 并获取 auth_code。

以下是我到目前为止为身份验证流程编写的代码:

API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v2'
CLIENT_SECRETS_FILE = 'C:/Users/Tushar/Documents/Serato_Video_Intelligence/client_secret_youtube.json'
def get_service():
  global auth_code
  global auth_uri
  flow = client.flow_from_clientsecrets(
  CLIENT_SECRETS_FILE, 
  scope='https://www.googleapis.com/auth/yt-analytics.readonly',
  redirect_uri = "http://localhost:8080")
  flow.params['access_type'] = 'offline'
  flow.params['include_granted_scopes'] = True
  auth_uri = flow.step1_get_authorize_url()
  credentials = flow.step2_exchange(auth_code)
  http_auth = credentials.authorize(httplib2.Http())
  return build(API_SERVICE_NAME, API_VERSION, http=http_auth)
  
def execute_api_request(client_library_function, **kwargs):
  response = client_library_function(
    **kwargs
  ).execute()
        

if __name__ == '__main__':
  # Disable OAuthlib's HTTPs verification when running locally.
  # *DO NOT* leave this option enabled when running in production.
  #os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  youtubeAnalytics = get_service()
  execute_api_request(
      youtubeAnalytics.reports().query,
      ids='channel==XXXXXXXXXXXXXX',
      startDate='2019-04-12',
      endDate='2019-08-13',
      filters= 'video==XXXXXXXXXXXXXX',
      metrics='audienceWatchRatio,relativeRetentionPerformance',
      dimensions='elapsedVideoTimeRatio'
      
  )

当我运行这段代码时,我得到一个错误

  File "C:\Users\Tushar\Documents\Serato_Video_Intelligence\youtube_auth_testing.py", line 65, in <module>
    youtubeAnalytics = get_service()
  File "C:\Users\Tushar\Documents\Serato_Video_Intelligence\youtube_auth_testing.py", line 40, in get_service
    credentials = flow.step2_exchange(auth_code)
NameError: name 'auth_code' is not defined

我已经阅读了有关 Stack Overflow 和 Google 的文章,但一直无法弄清楚该怎么做。我当然知道我缺少几个步骤,但我无法解决它。

  • 您想通过 OAuth2 的授权过程检索访问令牌。
  • 您想使用 oauth2client 和 Python 来实现此目的。

如果我的理解是正确的,这个修改怎么样?

授权流程:

当通过OAuth2的授权过程检索访问令牌时,首先需要通过自己的浏览器授权范围。当范围被授权时,可以检索授权码。使用此代码,可以检索刷新令牌和访问令牌。

模式 1:

当你现在的脚本修改后,变成如下。本次修改请修改get_service().

修改后的脚本:

import httplib2
from apiclient.discovery import build
from oauth2client import client

def get_service():
    flow = client.flow_from_clientsecrets(
        CLIENT_SECRETS_FILE,
        scope='https://www.googleapis.com/auth/yt-analytics.readonly',
        redirect_uri='urn:ietf:wg:oauth:2.0:oob')
    flow.params['access_type'] = 'offline'
    auth_uri = flow.step1_get_authorize_url()
    print('Please go to this URL: {}'.format(auth_uri))
    auth_code = input('Enter the authorization code: ')
    credentials = flow.step2_exchange(auth_code)
    http_auth = credentials.authorize(httplib2.Http())
    return build(API_SERVICE_NAME, API_VERSION, http=http_auth)

或(来自the sample script of Reports: Query。)

def get_service():
    flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
    credentials = flow.run_console()
    return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
  • 当您 运行 脚本时,Please go to this URL: ### 会显示在终端中。请将其复制并粘贴到您的浏览器,并请授权范围。然后,请检索授权码,并将其粘贴到终端。通过此流程,可以检索访问令牌。
  • 在上面的脚本中,当脚本为运行时,每次都需要进行授权过程。所以如果你不想这样做,下面的模式2怎么样?

模式 2:

此模式中,当脚本为运行时,自动打开浏览器,手动授权作用域时,自动获取授权码。

修改后的脚本:

import httplib2
import os
from apiclient.discovery import build
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage

def get_service():
    SCOPES = 'https://www.googleapis.com/auth/yt-analytics.readonly'
    credential_path = os.path.join("./", 'tokens.json')
    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRETS_FILE, SCOPES)
        credentials = tools.run_flow(flow, store)
    http = credentials.authorize(httplib2.Http())
    return build(API_SERVICE_NAME, API_VERSION, http=http_auth)
  • 在上面的脚本中,当脚本为 运行 时,当存在 tokens.json 时,使用文件中的刷新令牌检索访问令牌。这样,在第 2 个 运行.
  • 之后不需要使用自己的浏览器的授权过程

模式 3:

最近,google_auth_oauthlib用于授权过程。例如,您可以在 here. When this is reflected to your script, get_service() becomes as follows. Also you can see this flow at here.

处看到它

修改后的脚本:

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

def get_service():
    SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly']
    TOKEN_FILE = 'token.pickle'
    creds = None
    if os.path.exists(TOKEN_FILE):
        with open(TOKEN_FILE, 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                CLIENT_SECRETS_FILE, SCOPES)
            creds = flow.run_local_server()
        with open(TOKEN_FILE, 'wb') as token:
            pickle.dump(creds, token)
    return build(API_SERVICE_NAME, API_VERSION, credentials=creds)
  • 脚本为运行时自动打开浏览器,手动授权作用域时自动获取授权码
  • 在上面的脚本中,当脚本为 运行 时,当存在 token.pickle 时,使用文件中的刷新令牌检索访问令牌。这样,在第 2 个 运行.
  • 之后不需要使用自己的浏览器的授权过程

注:

  • 在我的环境中,我可以确认当使用 youtubeAnalytics of youtubeAnalytics = get_service() 时,execute_api_request() 工作正常。如果您的情况出现错误,请确认是否启用了API。

参考文献:

如果我误解了您的问题并且这不是您想要的方向,我深表歉意。