OAuth2 身份验证

所有 AdWords API 调用都必须通过 OAuth2 授权。OAuth2 可让您的 AdWords API 客户端应用访问用户的 AdWords 帐号,而无需处理或存储用户的登录信息。

生成 OAuth2 凭据

要生成 OAuth2 凭据,请按以下步骤操作:

1. 确定您的应用类型

首先,为要构建的应用确定适当的应用类型。AdWords API 有两种应用类型选项:

  • 已安装应用(推荐)
  • 网络应用

请查看下表,了解哪种类型最适合您要构建的应用:

选择此应用类型 如果...
已安装应用(推荐)
  • 您正在使用一个顶级经理帐号管理所有 AdWords 帐号。
  • 您是首次使用的用户,或者想要使用最简单的设置快速上手。
  • 您的应用会管理包含多个用户的同一组 AdWords 帐号。
网络应用
  • 您希望以任何可授予您应用对 AdWords 帐号数据访问权限的用户身份进行验证。
  • 您希望轻松生成多个授权凭据,比如用于管理第三方帐号。
  • 您的应用需要回调网址。已安装应用流程不支持回调网址。

有关详情,请参阅有关已安装应用网络应用的 Google 身份平台 OAuth 文档。

2. 创建客户端 ID 和客户端密钥

确定应用类型后,请点击下面的相应标签,然后按照说明生成 OAuth2 客户端 ID 和客户端密钥:

已安装应用
  1. 打开 Google API 控制台凭据页面
  2. 从项目下拉菜单中,选择新建项目,输入项目名称并根据需要选择是否修改所提供的项目 ID。点击创建
  3. 在“凭据”页面上,选择创建凭据,然后选择 OAuth 客户端 ID
  4. 在“同意”屏幕上,系统可能会提示您设置产品名称;若如此,请点击配置同意屏幕,提供要求的信息,然后点击保存以返回到“凭据”屏幕。
  5. 应用类型选择其他,然后输入所需的任何附加信息。
  6. 点击创建
  7. 在随即显示的页面中,将客户端 ID客户端密钥复制到您的剪贴板,您在配置客户端库时需要用到这些信息。
有关客户端 ID 和客户端密钥的屏幕截图
网络应用
  1. 打开 Google API 控制台凭据页面
  2. 从项目下拉菜单中,选择新建项目,输入项目名称并根据需要选择是否修改所提供的项目 ID。点击创建
  3. 在“凭据”页面上,选择创建凭据,然后选择 OAuth 客户端 ID
  4. 在“同意”屏幕上,系统可能会提示您设置产品名称;若如此,请点击配置同意屏幕,提供要求的信息,然后点击保存以返回到“凭据”屏幕。
  5. 选择网络应用作为应用类型。按照说明输入 JavaScript 来源和/或重定向 URI。
  6. 点击创建
  7. 在随即显示的页面中,将客户端 ID客户端密钥复制到您的剪贴板,您在配置客户端库时需要用到这些信息。
有关客户端 ID 和客户端密钥的屏幕截图

3. 配置和使用客户端库

请按照下面的相应指南,在所用语言客户端库的配置中使用 OAuth2 凭据:

OAuth2 Playground

生成 OAuth2 凭据的另一种选择是使用 OAuth2 Playground。OAuth2 Playground 与 Google API 控制台配合使用,可让您手动创建 OAuth2 令牌。

OAuth2 Playground 适用于只需访问单个经理帐号或 AdWords 用户帐号的用户。如果您需要提示多个用户提供凭据,则可能最好使用上述基于客户端库的方法。

设置

获取客户端 ID 和客户端密钥

  1. 打开 Google API 控制台凭据页面
  2. 从项目下拉菜单中选择现有项目或新建项目。
  3. 在“凭据”页面上,选择创建凭据,然后选择 OAuth 客户端 ID
  4. 应用类型下,选择网络应用
  5. 获得授权的重定向 URI 下,添加一行:https://developers.google.com/oauthplayground
  6. 点击创建
  7. 记下所出现页面上的客户端 ID客户端密钥。您将在下一步中用到它们。

生成令牌

  1. 通过此链接前往 OAuth2 Playground,所到达的页面中一些重要的值应该已为您预先填充。
  2. 点击右上角的齿轮图标 ,然后选中标有 Use your own OAuth credentials 的框(如果尚未选中的话)。
  3. 请确保:
    • OAuth flow 设置为 Server-side
    • Access type 设置为 Offline(这可确保您获得刷新令牌和访问令牌,而不只是访问令牌)。
  4. 输入您在上面获取的 OAuth2 客户端 IDOAuth2 客户端密钥Playground 设置
  5. 在标记为 Step 1 - Select & authorize APIs 的部分中,在底部的文本框中输入以下网址(如果尚不存在),然后点击 Authorize APIs

    https://www.googleapis.com/auth/adwords

    授权 API

  6. 如果出现提示,请登录到要向其授予访问权限和进行授权的帐号。否则,请确认目前右上角的 Google 用户是您要取得凭据的 AdWords 帐号或经理帐号。

  7. 系统会提示您,您的应用希望管理您的 AdWords 广告系列。点击 Accept 以继续。

  8. 现在,在标记为 Step 2 - Exchange authorization code for tokens 的标签中,您应该会看到 Authorization code。点击 Exchange authorization code for tokensPlayground 授权代码令牌
  9. 如果一切顺利,您应该会看到系统已为您填写 Refresh tokenAccess token(您可能需要重新展开 Step 2 - Exchange authorization code for tokens 查看这些值): Playground 刷新令牌
  10. 刷新令牌连同客户端 ID客户端密钥复制到您选择的客户端库的配置文件中。请参见上文的说明为您选择的客户端库设置配置选项。

从您的客户端 ID 中移除 OAuth2 Playground

既然您已拥有刷新令牌,不再需要将 OAuth2 Playground 作为经过授权的重定向 URI,要从经过授权的重定向 URI 列表中移除它,请按以下步骤操作:

  1. 转到 Google API 控制台凭据页面
  2. 从项目下拉列表中选择您的项目。
  3. 在“凭据”页面上,点击客户端 ID 名称进行修改。
  4. 获得授权的重定向 URI 中移除 https://developers.google.com/oauthplayground。请注意,您必须至少留下一个重定向 URI。
  5. 点击保存

您现在拥有了 OAuth 凭据,可以发出 AdWords API 请求,为您选择的客户端库尝试代码示例

OAuth2 服务帐号

本节讨论如何使用服务帐号访问 AdWords API。

服务帐号是属于您的应用而不是个别最终用户的帐号。服务帐号允许网络应用和 Google 服务之间进行服务器到服务器的互动。您的应用会代表服务帐号调用 Google API,因此用户不会直接参与。

AdWords API 允许通过 G Suite 网域访问服务帐号。

服务帐号使用 OAuth2 流程,无需人工授权,但需要使用只有您的应用可以访问的密钥文件。

使用服务帐号主要有以下两个优势:

  • 对应用授予 Google API 访问权限的操作是作为配置步骤进行的,可以避免使用其他 OAuth2 流程所带来的复杂问题;用户不需要进行干预,应用也不必为避免将来需要用户干预而缓存令牌。
  • OAuth2 断言流程允许您的应用在必要时模拟其他用户。

服务帐号的替代方法

开发者通常会考虑使用服务帐号,因为他们需要在不进行用户干预的情况下,使用 OAuth2 以编程方式访问 API。

考虑到为 AdWords API 设置服务帐号访问权限的复杂性,我们建议使用一个更简单的替代方案来实现相同的目标,即使用 OAuth2 已安装应用流程,并持久保留刷新令牌。这样,如有必要,您的应用始终能够请求新的访问令牌。

此过程需要您根据上述已安装应用过程配置您的客户端库,从而对您的应用进行授权。因为 Google OAuth2 刷新令牌不会过期,所以,此过程只需执行一次。

前提条件

  • 您拥有的 G Suite 网域(如 mydomain.com 或 mybusiness.com)。
  • AdWords API 开发者令牌以及(可选)测试帐号。
  • 您使用的语言的客户端库

设置服务帐号访问权限

首先,您必须在 Google API 控制台中生成服务帐号密钥:

  1. 登录您的 G Suite 帐号后,打开 Google API 控制台
  2. 从右上角的项目下拉菜单中选择创建项目,提供所需的信息,然后点击创建。稍后,新项目将成为活动项目。
  3. 从左上角的菜单中选择 IAM 和管理员,然后从左侧边菜单中选择服务帐号
  4. 点击顶部的创建服务帐号
  5. 输入服务帐号的名称。
  6. 选中提供新的私钥,然后选择 JSON 或 P12 密钥类型。目前 Java、.NET、Perl、Ruby 和 PHP 客户端库支持 JSON;其他所有客户端库均应使用 P12。
  7. 选中启用 G Suite 全网域委派功能,然后在同意屏幕中输入产品名称。
  8. 点击创建。如果选择 P12 作为私钥格式,密钥文件将下载到您的计算机,并显示一个包含私钥密码的屏幕。请立即保存此密码,因为它不会再显示。您需要提供此密码才能使用 P12 私钥。

    如果您选择 JSON 作为私钥格式,则 JSON 密钥文件将下载到您的计算机。

    将 P12 或 JSON 密钥文件存储在只有您可以访问的安全位置。

  9. 新服务帐号显示在项目的服务帐号页面上。

安全考虑

考虑到 G Suite 的网域级控制,因此一定要保护允许服务帐号访问其获授权的 Google 服务的密钥文件。因为该服务帐号能够模拟网域中的任何用户,所以尤其需要强调这一点。

另一个好的做法是每个服务帐号只允许访问一个 Google API(使用下一节中描述的范围字段)。这是一种先发制人的措施,即使服务帐号的密钥文件被泄露,仍能限制攻击者可以访问的数据量。

授权进行模拟

执行以下步骤,将模拟能力授予服务帐号:

  1. 通过转到 https://admin.google.com/YOUR_DOMAIN/ManageOauthClients,将新的已获授权 API 客户端添加到您的 G Suite 网域中
  2. 使用您在上述步骤中为全网域委派启用服务帐号时所生成 P12 或 JSON 文件中的客户端 ID,将新的已获授权 API 客户端添加为客户端名称
  3. 输入以下内容作为 API 范围:

    https://www.googleapis.com/auth/adwords

  4. 对要向其授予模拟权的所有其他服务帐号重复此过程。

您现在即可使用服务帐号通过 OAuth2 断言流程访问您的 AdWords 帐号。

配置客户端库

请在下面选择您的语言,了解如何配置您的客户端库。

Java

请参阅 GitHub 中的说明为服务帐号配置客户端库

.NET

请参阅 GitHub 中的说明为服务帐号配置客户端库

Python

请参阅 GitHub 中的说明为服务帐号配置客户端库

PHP

请参阅 GitHub 中的说明为服务帐号配置客户端库

Perl

请参阅 GitHub 中的说明为服务帐号配置客户端库

Ruby

请参阅 GitHub 中的说明为服务帐号配置客户端库

优化 OAuth2 请求

如果您的应用不能在服务器、进程和线程之间共享凭据,就可能会向 Google 发送过多的请求。这可能导致我们的服务器对您的应用强制执行速率限制,造成性能下降。

本节介绍如何优化 OAuth2 凭据管理,以便您的应用可以与 AdWords API 进行高效互动。

凭据共享策略

跨 API 请求共享凭据可提高性能,并避免可能引发速率限制错误的过多开销。

您的凭据共享策略取决于您的应用设计:

在多线程应用中,应该为每个线程的会话提供相同的凭据。

在多进程或分布式应用中,要跨进程共享凭据,必须实现一些基础架构。您还应该确保线程不会被阻止,并且自己的实现中不存在争用的情况。

如果应用的每次处理中同时具有多进程/分布式和多线程,则应该同时使用这两种策略。

下面介绍了对单个 AdWords 帐号(例如层级结构中的顶级经理帐号)进行身份验证的这些策略。

然后描述了如何改变这些策略,以便对多个 AdWords 帐号进行身份验证。

多线程应用

多线程应用应在线程之间共享凭据。应同步执行对凭据的刷新,以避免出现争用情况。

运行时

该图显示了一个运行时,其中带有提取自会话(或用户)池的线程,可向 AdWords API 发出请求。请注意,每个会话应使用相同的凭据对象。在每个 API 请求中,由线程获得会话(或用户)。如果凭据需要访问令牌刷新,则必须同步执行,即凭据对象对线程必须是安全的,以避免出现争用情况。

客户端库可直接跨线程共享凭据。每个客户端库都有一个会话(或用户)对象,并带有可在其生命周期中重用的凭据。要跨线程共享凭据,只需使用相同的凭据构建每个会话即可。在所有客户端库中,凭据是当访问令牌期满时会对自身进行同步刷新的对线程安全的对象。

例如,在 Java 客户端库中,您可以将 Credential 创建为单实例模式,并在所有会话间共享。

多进程或分布式应用

要在多进程或分布式应用中共享凭据,需要实现对凭据的持久保留。为了确保多个进程或服务器不会同时尝试刷新凭据(从而导致刷新请求过多),我们建议在某中央位置主动刷新凭据,并在进程/服务器之间共享凭据。

例如,可以由独立的作业或服务负责周期性地刷新凭据,并且主动将其推送到数据存储,以供服务器池使用。

刷新

该图显示了定期运行的凭据刷新作业,并将凭据的属性写入数据存储。然后,每个服务器在向 API 发出请求之前都要获取凭据。

刷新作业

刷新作业会定期刷新凭据并将其存储在数据存储中。作业不应等到当前凭据到期才启动刷新,否则可能导致应用因缺少有效凭据而停止运行,开一个“天窗”。

较好的替代方法是定期强制刷新,每次都用新凭据替换数据存储中的凭据。刷新作业应该在当前凭据到期之前尽早运行,以便预留一些时间,防止出现瞬间失败。比如,可考虑先从每 15 分钟刷新一次开始。

数据存储

中央数据存储可用于在进程和服务器之间共享凭据。

您既可以使用现有的数据存储,也可以部署一个特定于服务器间凭据共享的数据存储。解决方案既可以是缓存服务器(如 MemcachedInfinispan),也可以是 NoSQL 数据存储(如 MongoDB)。

对于向 API 发出请求的所有服务器,数据存储必须提供可靠的接口。它应该面向快速读取操作进行优化,原因是服务器或进程对当前凭据的读取频率要高于刷新作业的更新频率。

请记住,对凭据必须进行安全存储

存储凭据时,应该随 access_token 存储计算出的 expiry_time(现在要 + expires_in)和 refresh_tokenexpiry_time 计算为 access_token 刷新请求的时间加上 expires_in 时间。

服务器池

池中的每个服务器或进程先从数据存储中获取最新的凭据,然后才发出请求。只要刷新作业成功运行,凭据就会有效。但是,如果刷新作业或数据存储失败,您应该有一个回退机制。

如果服务器或进程无法从数据存储获取凭据,或者凭据已过期,则服务器应刷新自己的凭据,以允许应用继续使用 API,直到问题解决。

在有多个线程的处理过程中,您应该使用上述共享策略在线程间共享凭据。

验证多个帐号的身份

为 AdWords 经理帐号生成的凭据可用于访问其所有子帐号。因此,对于具有单一经理帐号层级结构的用户,通常只需为顶级经理帐号生成凭据,即可为其下的所有 AdWords 帐号实现应用授权。

另一些情况下,您的应用必须访问在任何经理帐号层级结构中彼此都不相关的 AdWords 帐号。在这种情况下,对于不同的帐号(例如您访问的每个 AdWords 客户帐号,或您访问的独立层级结构中的每个顶级经理帐号),您应该生成并维护不同凭据。

只需进行小规模的修改,即可对多线程多进程/分布式应用采用相同的策略。使用共享数据存储时,必须通过帐号标识符 customerId 对凭据编制索引,以确保凭据与正确的帐号相关联。此外,刷新作业应保证对所有凭据进行刷新。如果关联了新帐号,则可能需要触发刷新作业。

最后,在多线程应用中,在其间共享凭据对象的线程应该操作于与该凭据对象关联的帐号上。

OAuth2 内部

就以下所涉及的详细信息而言,我们的客户端库会实现自动处理,因此只有在您对后台发生的情况感兴趣时,或者您没有使用我们的任何客户端库时,才需要继续阅读。

本部分的目标读者是熟悉 OAuth 2.0 规范并且了解如何结合使用 OAuth2 和 Google API 的高级用户。

范围

同一个访问令牌可授予对多个 API 的不同级别的访问权限。有一个称为 scope 的可变参数用于控制访问令牌允许的资源和操作集。在请求访问令牌期间,您的应用在 scope 参数中发送一个或多个值。

AdWords API 目前所使用的范围和已弃用的范围:

范围 含义
https://www.googleapis.com/auth/adwords AdWords API 的读/写访问权限。
https://adwords.google.com/api/adwords/ 此范围已弃用,不应再用于获取未来的授权。以前获授权的令牌将继续工作。

离线访问

AdWords API 客户端应用通常会请求进行离线访问。例如,当您的用户并未实际在线浏览您的网站时,您的应用可能会希望运行批处理作业。

要为某网络应用类型请求离线访问,请确保将 access_type 参数设置为 offline。您可以在 Google 的 OAuth2 指南中找到更多信息。

对于已安装应用类型,离线访问在默认情况下处于启用状态,因此您不必专门请求离线访问。

HTTP 请求标头

发送到 AdWords API 服务器的每个请求中的 HTTP 标头都必须包含以下形式的访问令牌

Authorization: Bearer THE_ACCESS_TOKEN

例如:

POST … HTTP/1.1
Host: …
Authorization: Bearer 1/fFAGRNJru1FTz70BzhT3Zg
Content-Type: text/xml;charset=UTF-8
Content-Length: …

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
  …
</soap:Envelope>

访问令牌和刷新令牌

在大多数情况下,您需要安全地存储刷新令牌以备将来使用。要详细了解如何请求访问令牌和刷新令牌,请阅读与您的应用类型相对应的指南:

访问令牌过期

访问令牌有一个过期时间(基于 expires_in 值),在过期后,令牌即会失效。您可以使用刷新令牌刷新过期的访问令牌。默认情况下,我们的客户端库会自动刷新过期的访问令牌。

发送以下问题的反馈:

此网页
AdWords API
AdWords API
需要帮助?请访问我们的支持页面