无法使用 OAuth2 为 AdWords 帐户生成刷新令牌

Posted

技术标签:

【中文标题】无法使用 OAuth2 为 AdWords 帐户生成刷新令牌【英文标题】:Unable to generate refresh token for AdWords account using OAuth2 【发布时间】:2014-03-25 18:58:27 【问题描述】:

我在使用 Python 为 AdWords API 生成刷新令牌时遇到问题,需要一些帮助。情况如下:

我有一个 AdWords 客户,我想通过 AdWords API 提取报告(我们现在有一个开发者令牌)。假设在 AdWords 中,客户帐户是 521-314-0974(编造)。这是我感到困惑的地方:

下面是生成我正在尝试工作的刷新令牌所需的以下代码 sn-p:

"""Generates a refresh token for use with AdWords."""

__author__ = 'Nathaniel Payne'

import sys
import urllib2

from oauthlib import oauth2

# Your OAuth 2.0 Client ID and Secret. If you do not have an ID and Secret yet,
# please go to https://console.developers.google.com and create a set.
CLIENT_ID = 'INSERT_CLIENT_ID_HERE'
CLIENT_SECRET = 'INSERT_CLIENT_SECRET_HERE'

# You may optionally provide an HTTPS proxy.
HTTPS_PROXY = None

# The AdWords API OAuth 2.0 scope.
SCOPE = u'https://adwords.google.com/api/adwords'
# This callback URL will allow you to copy the token from the success screen.
CALLBACK_URL = 'urn:ietf:wg:oauth:2.0:oob'
# The HTTP headers needed on OAuth 2.0 refresh requests.
OAUTH2_REFRESH_HEADERS = 'content-type':
                          'application/x-www-form-urlencoded'
# The web address for generating new OAuth 2.0 credentials at Google.
GOOGLE_OAUTH2_AUTH_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
GOOGLE_OAUTH2_GEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'


def main():
  oauthlib_client = oauth2.WebApplicationClient(CLIENT_ID)

  authorize_url = oauthlib_client.prepare_request_uri(
      GOOGLE_OAUTH2_AUTH_ENDPOINT, redirect_uri=CALLBACK_URL, scope=SCOPE)
  print ('Log in to your AdWords account and open the following URL: \n%s\n' %
         authorize_url)
  print 'After approving the token enter the verification code (if specified).'
  code = raw_input('Code: ').strip()

  post_body = oauthlib_client.prepare_request_body(
      client_secret=CLIENT_SECRET, code=code, redirect_uri=CALLBACK_URL)
  if sys.version_info[0] == 3:
    post_body = bytes(post_body, 'utf8')
  request = urllib2.Request(GOOGLE_OAUTH2_GEN_ENDPOINT, post_body,
                            OAUTH2_REFRESH_HEADERS)
  if HTTPS_PROXY:
    request.set_proxy(HTTPS_PROXY, 'https')
  raw_response = urllib2.urlopen(request).read().decode()
  oauth2_credentials = oauthlib_client.parse_request_body_response(raw_response)

  print ('Your access token is %s and your refresh token is %s'
         % (oauth2_credentials['access_token'],
            oauth2_credentials['refresh_token']))
  print ('You can cache these credentials into a yaml file with the '
         'following keys:\nadwords:\n  client_id: %s\n  client_secret: %s\n'
         '  refresh_token: %s\n'
         % (CLIENT_ID, CLIENT_SECRET, oauth2_credentials['refresh_token']))


if __name__ == '__main__':
  main()

问题: 1) 我是否需要在 console.developers.google.com 中为每个 AdWords 客户设置一个特殊的项目,以便从 AdWords Reporting API 中提取?或者,我可以简单地在控制台中提供通用帐户的客户端密码和 ID?

2) 在此之后,有人可以确认应该用什么来代替 client_ID 和 Client_Secret 以使下面的 Python 代码块正常工作。我的意思是,我正在使用来自 https://console.developers.google.com 的客户端 ID 和客户端密码......用于我们设置了计费的分析帐户(并且我之前已将其用于 BigQuery API 访问)。那是对的吗?我不清楚这将如何与该客户的 AdWords 帐户相关联。

2) 在同意屏幕中,我输入了我自己的电子邮件,因为我是该项目的所有者。也就是说,当我运行代码时,我会获得指向我需要运行以生成代码的 URL 的链接。也就是说,当我晒这个 sn-p 时:

print ('Log in to your AdWords account and open the following URL: \n%s\n' %
             authorize_url)
      print 'After approving the token enter the verification code (if specified).'
      code = raw_input('Code: ').strip()

我得到一个错误。这是我收到的错误消息:

Error: redirect_uri_mismatch
The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob did not match a registered redirect URI

Learn more
    Request Details
    cookie_policy_enforce=false
    scope=https://adwords.google.com/api/adwords
    response_type=code
    access_type=online
    redirect_uri=urn:ietf:wg:oauth:2.0:oob
    display=page
    client_id=XXXXXXXXX.apps.googleusercontent.com

我在这里感到困惑。有些人建议更改同意屏幕中的电子邮件地址(我这样做了……但没有成功)。同样,我的简单目标是能够通过 AdWords API 从客户那里提取一份报告(一旦我到达那里,我将对其进行扩展)。任何帮助,将不胜感激。干杯。

【问题讨论】:

【参考方案1】:

经过一些工作,我能够成功解决这个问题。以下是我为成功通过 API 提取数据而采取的详细步骤。在我的情况下,我管理具有多个帐户的 AdWords MCC。因此,我回到了许多帮助手册的开头并做了以下操作:

    创建一个名为 AdWords-API-XXXX 的新项目。 在控制台的凭据屏幕中,我创建了一个新的“本地应用程序的客户端 ID”。这使我能够生成我需要的 CLIENT_ID 和 CLIENT_SECRET。至关重要的是,它还生成了一个重定向 URI,这是我的问题的根源。 我获取了这两个值,将它们添加到主脚本中,然后运行 ​​generate_refresh_token.py 脚本。这使我能够生成一个有效的刷新令牌。我必须登录到我的 AdWords 帐户 MCC,以确保 OAuth2 使我能够访问我的 MCC 中的所有潜在 AdWord 客户。我收到了一个由 URL 为该过程生成的身份验证屏幕,要求我确认是否已授予 AdWords 访问权限。

    在此之后,我创建了一个新的 googleads.yaml 脚本并将其放置在我的 c:\gsutil 目录中。这是大多数 Python 程序中查找文件 googleads.yaml 的代码:

    adwords_client = adwords.AdWordsClient.LoadFromStorage()
    

    完成此操作后,我就能够从命令行成功运行脚本以生成最终输出。脚本是:

    python download_criteria_report.py
    

当然请注意,我之前更改了路径变量,以便从命令行运行 Python 2.7。该脚本在 download_criteria_report.py 文件的目录中运行。该脚本运行成功,使我能够从 AdWords API 中为我的一个测试客户提取数据。

下一个挑战将是处理从 API 返回的输出,并将其转换为我可以快速用于分析和存储的格式。

【讨论】:

好帖子,对新手很有帮助,好像还缺乏详尽的指南! 谢谢。很高兴它有帮助。我也有同样的感觉。我正在慢慢研究 Google Cloud 堆栈,并会随时发布问题(如果我找到了解决方案,或者其他人找到了解决方案,我也会一起发布)。 当我使用 generate_refresh_token.py 时,它给了我一个刷新令牌,这和开发人员令牌一样吗?您的 googleads.yaml 文件是什么样的? 哦,纳米,刚刚发现这个:github.com/googleads/googleads-python-lib/blob/master/…

以上是关于无法使用 OAuth2 为 AdWords 帐户生成刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

Google Adwords API with OAuth2 如何获取授权用户的电子邮件?

使用 suds 在 Python 中使用 OAuth2 进行 Google Adwords API 身份验证

为啥即使帐户已关联,我也无法将转化事件从 Firebase 导入 AdWords?

在没有刷新令牌的情况下获取 AdWords customerId

“Invalid_client”为 Adwords API 生成 oAuth2 令牌

无法使 GetRefreshToken.php 与 Adwords API 一起使用