API 授权

在访问酒店 API 时,使用 OAuth 2.0 向您的应用授权。

OAuth 2.0 设置

OAuth 2.0 要求您使用与自己的 Google 帐号相关联的服务帐号来识别您自己的身份。服务帐号会发送您的私钥来换取 OAuth 2.0 访问令牌。然后,您可以在调用酒店 API 时使用此令牌来获取只读数据,例如有关酒店价格 Feed 的价格、酒店和诊断报告数据。

访问令牌的有效期为一小时(3600 秒)。

如果您之前实现了 CMEK,则 OAuth 2.0 方法与此类似,但存在以下差异:

  • 您的应用使用 Google 服务帐号来访问 API。
  • 调用 API 时,您需要在 Authorization HTTP 标头中传递 OAuth 2.0 访问令牌。

要设置您的帐号以便通过 Travel Partner API 使用 OAuth 2.0,请按以下步骤操作:

  1. 在 Google Developers Console (DevConsole) 中创建一个新项目

  2. 为新项目启用对 Travel Partner API 的访问权限

  3. 创建服务帐号及其凭据

  4. 向服务帐号授予酒店数据的访问权限

后续几个部分将介绍其中每个步骤。

第 1 步:创建新的 DevConsole 项目

Google Developers Console(简称“DevConsole”)是 Google 面向开发者提供的一种平台,可用来管理和查看项目使用的 Google API 的流量数据、身份验证和结算信息。

在 DevConsole 中,项目包含关于您正在使用的一个或多个应用(使用了 Google Developer API 和 Google Cloud 资源)的设置、凭据和元数据的集合。

在 DevConsole 中,您可以管理项目的方方面面,例如生成 API 凭据、激活 API 以及管理与项目相关的团队和结算信息。

如需创建新的 DevConsole 项目,请执行以下操作:

  1. 登录您的 Gmail/Google 帐号。

  2. 打开 Google 开发者控制台。如果这是您的第一个项目,主视图会显示一个简单的 CREATE PROJECT(创建项目)按钮:

    fig1

  3. 点击创建项目按钮。DevConsole 会显示 New Project 对话框:

    fig2

    项目名称输入字段中输入新项目的易记名称。在该字段下方,DevConsole 会为您生成一个项目 ID,以确保此 ID 在所有项目中都是唯一的。例如,如果您输入“My New Project”,DevConsole 会分配一个类似 my-new-project-266022 的 ID。

  4. 点击 Create 按钮以创建新项目。

  5. 使用导航菜单,依次选择 API 和服务 > 信息中心

    fig3

    下图显示了 Developer Console 左上角的导航菜单。此时将显示项目的“信息中心”视图:

    fig4

如需了解详情,请参阅在 Developers Console 中管理项目

当您创建新项目时,该项目还没有关联的 API。在下一步中,您将为新项目启用 Travel Partner API

第 2 步:为新项目启用 Travel Partner API

若要使用酒店 API,您必须在新的开发者控制台项目中启用 Travel Partner API

如需为新项目启用酒店 API,请执行以下操作:

  1. 按照上述说明转到项目的“信息中心”视图。

  2. 点击启用 API 和服务。系统会显示 API 库欢迎页面。

  3. 在搜索字段中,开始输入 Travel Partner API。 Google API 控制台会显示与您输入的类型匹配的 API 列表。

  4. 点击匹配 API 表格中的 Travel Partner API。DevConsole 会显示有关该 API 的说明。

  5. 点击启用 API 按钮,为您的项目启用此 API。

如需了解详情,请参阅启用和停用 API

您 Google 帐号的新项目现已启用 Hotel API。

下一步是创建服务帐号并为其生成密钥。

第 3 步:创建服务帐号并生成其凭据

服务帐号用于服务器到服务器的互动,例如 Web 应用和酒店数据之间的互动。

如需创建和配置服务账号,请执行以下操作:

  1. 在 Google API 控制台主视图中,点击左侧导航栏中的凭据。DevConsole 会显示凭据视图。

    凭据视图会显示项目的客户端 ID 和凭据。您的应用将在请求 OAuth 2.0 访问令牌时使用客户端 ID。新项目还没有客户端或凭据。

  2. 点击 API 和服务中的凭据链接。

  3. 点击创建凭据按钮,然后从下拉菜单中选择服务帐号密钥。此时将显示创建服务帐号密钥视图。

  4. 服务帐号下拉列表中,选择新建服务帐号

  5. 输入服务帐号名称和服务帐号 ID。

    您可以随意指定名称,但帐号 ID 在所有项目中必须是唯一的。DevConsole 将根据您输入的名称为您生成一个唯一的帐号 ID。

  6. 选择 P12 作为密钥类型,如下所示。P12 是必需的

    fig5

  7. 点击创建按钮。DevConsole 会为您的项目生成私钥/公钥对。私钥将保存到浏览器存储下载内容的默认位置。您必须下载 .p12 格式(二进制文件),而不是 .json 文件格式。

    您可以在用于访问 Travel Partner API 的脚本或其他应用中使用私钥。

    DevConsole 完成密钥生成后会显示以下通知:

    fig6

  8. 点击好,知道了按钮。开发者控制台会将您返回到凭据视图。如需确认服务帐号的详细信息并查看与项目关联的服务帐号,请点击此视图中的管理服务帐号

    该服务账号现在具有以下关联凭据:

    • 客户端 ID:您的应用在请求 OAuth 2.0 访问令牌时使用的唯一标识符。
    • 电子邮件地址:为服务账号生成的电子邮件地址,格式为“account_name@project_name.google.com.iam.gserviceaccount.com”。
    • 证书指纹:您下载的私钥的 ID。

如需了解详情,请参阅针对服务器到服务器应用使用 OAuth 2.0

第 4 步:向服务帐号授予对 Hotel Center 数据的访问权限

最后一步是为新服务帐号提供对 Hotel Center 的访问权限。服务帐号由您在上一步中创建的生成电子邮件地址标识。您可以使用 Hotel Center 共享设置提供此帐号的访问权限。

如需向服务帐号授予对 Hotel Center 数据的访问权限,请执行以下操作:

如果您没有适当的访问权限,无法向帐号添加用户,请使用与我们联系表单与 Google 酒店团队联系,请求我们为您的帐号设置所有权。您可以请求向所有者发送一封或多封电子邮件。 如需详细了解 Hotel Center 访问权限,请参阅将 Hotel Center 与 Google Ads 相关联

  1. 在新的浏览器窗口中,打开 Hotel Centerfig7

  2. Hotel Center by Google 横幅上,点击“添加用户”图标以打开共享对话框。

    fig8

  3. 添加更多用户字段中,输入要添加到 Hotel Center 的服务帐号的电子邮件地址。

  4. 保持通知对方选项处于选中状态。

  5. 从下拉菜单中选择管理

  6. 点击邀请按钮。

  7. 将用户添加到 Hotel Center 后,系统应该会在大约 24 小时内为您的服务帐号启用 API 访问权限。

在 Google 通知您已为服务帐号启用 API 访问权限后,您就可以开始使用 OAuth 访问 API。

使用 OAuth 2.0

如需访问该 API,您的应用必须使用服务帐号生成的电子邮件地址和私钥向 Google 标识自己。Google 的身份验证机制会将此密钥替换为 OAuth 2.0 访问令牌,供您在应用 API 调用的 Authorization 标头中传递。

访问令牌(也称为不记名令牌)是 OAuth 2.0 标准的一部分。在 HTTP 标头中指定访问令牌的语法如下:

Authorization: Bearer *oauth2_access_token*

以下示例展示了访问 Reports API 的请求的 HTTP 标头示例:

GET /travelpartner/v2.0/42000042/reports/top_opportunity_7_day HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer nd42.fdLSKkljD98344444444444lSDF42fdLSKkljD98344444444444lSDF42
Cache-Control: no-cache

如需生成访问令牌,请使用您选择的任意语言创建应用。 以下示例在 Python 中生成令牌。然后,当访问 Travel Partner API 时,您可以在请求的 Authorization 标头中使用此令牌。

#!/usr/bin/python2.7
#
""" Sample code to get an auth header that you can use in your HTTP requests
    1. Please see https://developers.google.com/api-client-library/python/start/installation
       to download and install the google-api-python-client package.
    2. Edit lines below marked _SERVICE_ACCOUNT, _KEY_FILE,  _PARTNER_NAME,
       and _API_VERSION.
    3. Run the program using: "python sample.py". The app returns the value that
       you use for the Authorization header's Bearer token in your request.
    4. Copy the token and use it in requests to the Travel Partner API.
       For example (2.0):
       https://www.googleapis.com/travelpartner/2.0/42000042/reports/budget
       For example (1.x):
       https://www.googleapis.com/travelpartner/1.2/reports?report_type=BUDGET
"""
import httplib2
import json
import os
import sys
import urllib

HAS_CRYPTO = False

from apiclient import discovery
from oauth2client.client import flow_from_clientsecrets
try:
  # Some systems may not have OpenSSL installed so can't use SignedJwtAssertionCredentials.
  from oauth2client.client import SignedJwtAssertionCredentials
  HAS_CRYPTO = True
except ImportError:
  print "Unable to import SignedJwtAssertionCredentials"

from oauth2client import tools
from oauth2client.file import Storage

# Authorization scope for our requests (do not change)
_DEFAULT_APISCOPE = 'https://www.googleapis.com/auth/travelpartner'

# Use the service account you set up in the Google Developers Platform.
# It will be of the form "gsaccount_name@project_name.google.com.iam.gserviceaccount.com".
_SERVICE_ACCOUNT = ('myserviceaccount@my-hotel-project.google.com.iam.gserviceaccount.com')

# Set this to the full path to your service account's private binary .p12 key file
# that you downloaded from the Google Developer's Console and stored in a secure place.
# DO NOT use the json version of the certificate.
_KEY_FILE = '../mylocaldir/api-keys/8482bb2bdb08.p12'

# Set this to the case-sensitive "Partner Key", NOT the account
# name in the Hotel Ads Center or the numeric partner ID.
# Check with your TAM if you do not know your "Partner Key" name.
_PARTNER_NAME = 'testpartner2'

class HotelAdsAPIConnection(object):
  def __init__(self, service_account=_SERVICE_ACCOUNT, key=_KEY_FILE, partner=_PARTNER_NAME):
    self.key_file = key
    self.account = service_account
    self.partner = partner

  def InitializeCredentials(self, scope):
    '''Get credentials for use in API requests.
    Generates service account credentials if the key file is present,
    and regular user credentials if the file is not found.
    '''
    if os.path.exists(self.key_file):
      if not HAS_CRYPTO:
        raise Exception("Unable to use cryptographic functions "
                        + "Try installing OpenSSL")
      with open (self.key_file, 'rb') as file:
        key = file.read();
      creds = SignedJwtAssertionCredentials(self.account, key, scope)
      self.credentials = creds

  def authorize(self):
    '''Construct a HTTP client that uses the supplied credentials.'''
    return credentials.authorize(httplib2.Http())

  def print_creds(self):
    '''Prints the Authorization header to use in HTTP requests.'''
    cred_dict = json.loads(self.credentials.to_json())

    if 'access_token' in cred_dict:
      print 'Authorization: Bearer %s' % (cred_dict['access_token'],)
    else:
      print 'creds: %s' % (cred_dict,)

  def GetConnection(self):
    http = httplib2.Http()
    self.credentials.refresh(http)
    http = self.credentials.authorize(http)
    self.print_creds()
    return http

def main(args):
  # Create an instance of the HotelAdsAPIConnection inner class
  api = HotelAdsAPIConnection()

  # Generate credentials
  api.InitializeCredentials(_DEFAULT_APISCOPE)

  # Output the Authorization header to use in HTTP requests
  api.GetConnection()

if __name__ == "__main__":
    main(sys.argv)</pre>

在开发应用时,请务必遵循安全使用 API 密钥的最佳实践

示例 Python 脚本会输出 Authorization 标头的 Bearer 令牌,如以下示例所示:

$ python sample.py
Authorization: Bearer ya29.42424242sample_420icu8122KSvoh4T42cRoG3rW1lc0Q
$

在请求中使用令牌的值。生成后 1 小时内有效。

问题排查

遇到问题了?快速检查以下内容可能会解决问题。

  1. 您是否在 Google Developer Console 中创建了项目?
  2. 找到并启用Travel Partner API了吗?
  3. 您是否在点击创建客户端 ID 并选择服务帐号后下载了 .p12 文件(私钥)?
  4. 您是否获得了以下形式的服务帐号客户端 ID 电子邮件地址:nnnnnnn@app_name.google.com.iam.gserviceaccount.com
  5. 您是否通过点击共享此帐号按钮与服务帐号共享了 Hotel Ads Center 帐号?
  6. 您是否已将服务帐号的电子邮件地址和合作伙伴 ID 发送给您的技术支持客户经理 (TAM)?
  7. 您的 Travel Partner API 调用在 Authorization 标头中是否传递了最近获取的令牌?
  8. 您的 Authorization 标头的不记名令牌的存在时间是否超过 1 小时?

下表列出了一些常见错误以及可能的解决方法:

错误 说明
Invalid credentials 这可能涉及很多问题。如果您遇到此错误,请检查以下各项:
  • 您指定的 Authorization 标头具有有效的不记名令牌。
  • 不记名令牌的存在时间不到一小时。令牌的有效期只有一小时。
  • 您指定了正确的合作伙伴名称(使用 partner 查询字符串参数)。该值是您的唯一合作伙伴 ID,而不是 Hotel Ads Center 中显示的合作伙伴名称。如果您不知道自己的合作伙伴 ID,请与您的技术支持客户经理 (TAM) 联系。
Not found 您的端点格式很可能有误。请确认您提交的是 GET 请求,以及请求网址是否有效(该网址符合您尝试访问的 API 语法)。
Invalid string value 端点的一个或多个部分包含无效语法。例如,您可能拼错了路径的一部分。检查并确保在整个路径中使用正确的下划线、大小写和措辞。
Unsupported output format 此错误最常在使用 Reports API 时发生。您必须在 GET 请求的网址中指定 "alt=csv"。Reports API 不支持 JSON。
AccessTokenRefreshError/Invalid grant 运行示例 Python 应用时,此错误可能由以下原因引起:
  • 您的服务帐号电子邮件地址不正确。在 Google 开发者控制台中检查电子邮件帐号,并确保它有权访问该 API。
  • 此电子邮件地址没有 API 访问权限。检查该电子邮件地址是否有权访问您的酒店数据(通过 Hotel Center 共享)。
  • 密钥文件不是服务帐号的正确密钥文件。使用开发者控制台下载新的 .p12 证书,并确保您的 Python 应用指向正确的证书。
HotelAdsAPIConnection object has no attribute credentials 运行示例 Python 应用时,.p12 文件的路径不正确。
Invalid scope 运行示例 Python 应用时,API 范围必须为 https://www.googleapis.com/auth/travelpartner
Forbidden 您使用的帐号 ID 是您无权访问的帐号 ID。如果您是子帐号所有者,则可能无法访问父级帐号或根帐号 ID。