将 OAuth 与 Google Data API 搭配使用

Eric Bidelman,Google Data API 团队
2008 年 9 月

简介

对于开发者来说,这是一个激动人心的时代。我们开始看到许多开放标准被网络广泛采用,而且正如您所知,Google 一直非常支持标准,并积极推动开源社区的发展。

最近,所有 Google Data API 都开始支持 OAuth,这是一种开放式协议,旨在标准化桌面应用和 Web 应用访问用户非公开数据的方式。OAuth 提供了一种以标准且安全的方式执行 API 身份验证的方法。作为程序员,我们被教导要尽可能重用代码。OAuth 将帮助开发者减少编写的重复代码量,并更轻松地创建可与各种不同提供商提供的多种服务搭配使用的工具。

受众群体

本文假定您熟悉一种或多种 Google Data API,但不一定了解 OAuth 背后的概念。 如果您是新手,或者只是对 OAuth 感兴趣,那么本文正适合您。本文将为您奠定扎实的概念基础。我还会讨论 Google OAuth 实现的详细信息。

本文档还面向熟悉使用 AuthSub 的开发者,尤其是以注册并增强安全性模式使用 AuthSub 的开发者。在接下来的内容中,我会尽量突出显示这两种协议之间的相似之处不同之处。如果您有使用 AuthSub 的应用,可以根据此信息迁移到 OAuth,这是一个更开放、更现代的协议。


一些术语

了解 OAuth 的关键在于了解其术语。OAuth 规范和 Google 的适用于 Web 应用的 OAuth 身份验证文档在很大程度上依赖于某些定义,因此我们来明确一下在 Google 的 OAuth 实现中,每个定义分别意味着什么。

  1. “OAuth 交互”

    我用来描述完整 OAuth 身份验证/授权流程的非正式术语。

  2. (OAuth) 请求令牌

    一种初始令牌,用于告知 Google 您的应用正在请求访问某个 Google Data API。OAuth 流程的第二步是用户手动授予对其数据的访问权限。如果此步骤成功,请求令牌将获得授权。

  3. (OAuth) 访问令牌

    OAuth 流程的最后一步是将授权的请求令牌换成访问令牌。应用获得此令牌后,用户无需再次执行 OAuth 流程,除非令牌被撤消。

    与 AuthSub 的相似之处
    OAuth 访问令牌与安全的 AuthSub 会话令牌相同。

  4. (OAuth) 端点

    这些是验证应用身份并获取访问令牌所需的 URI。共有三个,分别对应 OAuth 流程的每个步骤。 Google 的 OAuth 端点如下:

    获取请求令牌:https://www.google.com/accounts/OAuthGetRequestToken
    授权请求令牌:https://www.google.com/accounts/OAuthAuthorizeToken
    升级为访问令牌:https://www.google.com/accounts/OAuthGetAccessToken

    与 AuthSub 的相似之处
    将授权请求令牌换成访问令牌类似于在 https://www.google.com/accounts/AuthSubRequestTokenhttps://www.google.com/accounts/AuthSubSessionToken 中将一次性 AuthSub 令牌升级为长期有效的会话令牌。 不同之处在于,AuthSub 没有初始请求令牌的概念。用户应从 AuthSubRequestToken 授权页面开始令牌流程。

  5. (OAuth) 服务提供商

    对于 Google Data API,此提供方是 Google。一般来说,服务提供商用于描述提供 OAuth 端点的网站或 Web 服务。OAuth 服务提供商的另一个示例是 MySpace。

  6. (OAuth) 使用方

    请求访问用户数据的程序(即您的应用)。OAuth 协议非常灵活,可支持各种不同类型的客户端(Web、已安装、桌面、移动)。

注意:虽然 OAuth 协议支持桌面/已安装的应用用例,但 Google 仅支持 Web 应用的 OAuth。

使用入门

注册

在开始将 OAuth 与 Google Data API 搭配使用之前,您需要进行少量设置。由于所有 OAuth 请求都必须进行数字签名,因此您首先需要注册网域并向 Google 上传公共证书。如需详细了解如何执行此操作,请参阅基于 Web 的应用的注册生成密钥和证书以用于注册模式

对请求进行签名

注册域名后,您就可以开始签署请求了。OAuth 最难理解的概念之一是如何正确构建 oauth_signature 以及签名基字符串的概念。基本字符串是您使用私钥(通过 RSA_SHA1)进行签名的数据。结果是您为 oauth_signature 设置的值。

示例请求

GET 用户的 Google 日历列表,位于 http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime

基本字符串格式 base_string = http-method&base-http-request-url&normalized-string-of-oauth_parameters
基本字符串示例 GET&http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull&oauth_consumer_key%3Dexample.com%26oauth_nonce%3D4572616e48616d6d%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D137131200%26oauth_token%3D1%252Fab3cd9j4ks73hf7g%26oauth_version%3D1.0%26orderby%3Dstarttime
HTTP 请求示例
GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime HTTP/1.1
Host:  http://www.google.com
Content-Type: application/atom+xml
Authorization: OAuth oauth_token="1%2Fab3cd9j4ks73hf7g", oauth_signature_method="RSA-SHA1", oauth_signature="wOJIO9AvZbTSMK%2FPY%3D...", oauth_consumer_key="example.com", oauth_timestamp="137131200", oauth_nonce="4572616e48616d6d", oauth_version="1.0"

注意:这仅用于表示。您的 oauth_signature 将会更长。

关于基本字符串的注意事项:

  • orderby=starttime 查询参数会与其余 oauth_* 参数一起按字典顺序的字节值排序。
  • 此字符串也包含“?”字符。
  • base-http-request-url 部分仅包含网址编码的基准网址:http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull
  • oauth_token 经过了两次网址编码。

关于 Authorization 标头的注意事项:

  • Authorization 标头中,oauth_* 参数的顺序无关紧要。
  • 标头不包含 orderby=starttime,而基本字符串包含。该查询参数会保留在请求网址中。

如需详细了解如何使用 OAuth 对请求进行签名,请参阅对 OAuth 请求进行签名

与 AuthSub 的区别
为了进行比较,下面是使用安全 AuthSub 的相同示例:

基本字符串格式 base_string = http-method http-request-URL timestamp nonce
基本字符串示例
GET http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fdefault%2Fallcalendars%2Ffull%3Forderby%3Dstarttime 137131200 4572616e48616d6d
HTTP 请求示例
GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime HTTP/1.1
Host:  http://www.google.com
Content-Type: application/atom+xml
Authorization: AuthSub token="GD32CMCL25aZ-v____8B" data="GET http://www.google.com/calendar/feeds/default/allcalendars/full?orderby=starttime 137131200 4572616e48616d6d" sig="MCwCFrV93K4agg==..." sigalg="rsa-sha1"

如需详细了解如何使用 AuthSub 对请求进行签名,请参阅对 AuthSub 请求进行签名

OAuth Playground 工具

用途

一些用户认为 OAuth 的学习曲线较陡峭。与其他 Google 身份验证 API 相比,我同意这种说法。当您扩展应用以使用其他(非 Google)服务时,OAuth 的优势就会显现出来。编写一段适用于不同服务提供商及其 API 的身份验证代码,这对我来说非常有用。您现在学习该协议,以后会感谢自己。

OAuth Playground 是我创建的一款工具,旨在帮助开发者解决 OAuth 相关问题。 您可以使用 Playground 调试问题、检查自己的实现或试用 Google Data API。

它的用途是什么?

  1. 演示 OAuth 身份验证流程:获取请求令牌、授权令牌并将其升级为访问令牌。
  2. 显示每个请求的正确签名基本字符串。
  3. 针对每个请求显示正确的 Authorization 标头。
  4. 演示了如何使用 oauth_token 与经过身份验证的 Google 数据 Feed 进行交互。您可以GET/POST/PUT/DELETE数据。
  5. 直接在浏览器中查看经过身份验证的 Feed。
  6. 允许您测试自己的 oauth_consumer_key(您注册的网域)和私钥。
  7. 了解 oauth_token 可使用哪些 Google 数据 Feed 服务。

演示运行

第 1 步:选择您的范围

首先,选择一个或多个范围,确定要使用的 API。在此演示中,我请求了一个可用于 Blogger Google 通讯录的令牌。

与 AuthSub 的相似之处
AuthSub 也需要使用 scope 参数来控制令牌可访问的数据范围。Google 已按照 OAuth 规范中的建议实现了此参数。

第 2 步:修改 OAuth 参数和设置

目前,请勿修改“修改 OAuth 参数”框中的任何设置。稍后,您可以将 oauth_consumer_key 更改为已注册的网域,然后点击“使用您自己的私钥”输入您的私钥,从而使用自己的私钥进行测试。请仅使用测试私钥。

注意oauth_signature_methodoauth_consumer_key 是此处唯一可修改的字段。系统会自动为您生成 oauth_timestampoauth_nonceoauth_token

除了 RSA-SHA1 之外,您还可以选择使用 HMAC-SHA1 作为 oauth_signature_method。在这种情况下,Playground 会显示其他框,您需要在其中输入自己的 oauth_consumer_key 和使用方密文。您可以在注册网域的 https://www.google.com/accounts/ManageDomains 页面中找到这些值。

与 AuthSub 的区别
在安全 AuthSub 中,没有用于明确设置网域名的参数。网域包含在 next 网址参数中。 OAuth 中有这样一个参数:oauth_consumer_key。将其设置为您注册的网域。

第 3-5 步:获取访问令牌

获取 OAuth 访问令牌需要三个步骤。第一步是检索请求令牌。这可让 Google 知道您的应用正在开始 OAuth 流程。

首先,点击“获取令牌”框中的“请求令牌”按钮。

某些字段将填充数据。

  • “签名基准字符串”会显示用于创建 oauth_signature 参数的基准字符串的正确形式。
  • “授权标头”会显示相应请求的 Authorization 标头。
  • “修改 OAuth 参数”框中填充了请求中发送的 oauth_nonceoauth_timestamp 值。
  • oauth_token 输入已填充响应正文中返回的相应值。Playground 还会显示我们当前拥有的 oauth_token 类型。目前,它是请求令牌。

接下来,点击“获取令牌”框中的“授权”按钮。

在此授权页面上,点击“授予访问权限”按钮以授权请求令牌,然后系统会将您重定向回 OAuth Playground。

与 AuthSub 的相似之处
此授权页面与 AuthSub 的相同。

与 AuthSub 的区别
AuthSub 的 next 网址参数类似于 oauth_callback 参数。不同之处在于,在 OAuth 中,oauth_callback 是可选的。用户点击“授予访问权限”按钮后,请求令牌会获得授权,并且可以异步执行令牌升级到 https://www.google.com/accounts/OAuthGetAccessToken 的操作。

提示:如果您要编写 Web 应用,最好指定 oauth_callback 网址,因为这样可以提供更好的用户体验。

最后,点击“获取令牌”框中的“访问令牌”按钮。

此操作会升级授权的请求令牌(如红色“访问令牌”标签所示)。

如果您想获取新令牌,请点击“重新开始”以重新启动 OAuth 流程。

现在,我们可以做一些有趣的事情了!

使用访问令牌

现在,您就可以查询 Feed、插入、更新或删除数据了。在执行最后三种 HTTP 方法时,请务必谨慎操作,因为您正在处理真实数据!

提示:如需发现可供您的访问令牌使用的 Feed,请点击“可用的 Feed”按钮。

以下是一个查询示例:GET http://www.blogger.com/feeds/1982051675575479214/posts/default?max-results=3

此示例返回特定博客上的帖子,但数量不超过 3 篇。您还可以点击语法突出显示区域下方的“在浏览器中查看”链接,直接在浏览器中查看返回的 Feed/条目。

示例:如何更新帖子

  1. 在要更新的帖子中找到带有 rel="edit"<link> 元素。它应如下所示:
    <link rel="edit" href="http://www.blogger.com/feeds/1982051675575479214/posts/default/8138973184593279875"/>

    href 网址粘贴到“输入 Google 数据 Feed”输入框中。

  2. 点击语法突出显示面板顶部的“查看纯文本”,复制现有条目的 XML。仅复制响应正文,不复制标头。
  3. 将 HTTP 方法下拉菜单更改为 PUT
  4. 点击该下拉菜单下方的“输入帖子数据”,然后将 <entry> XML 粘贴到弹出式窗口中。
  5. 点击“执行”按钮。

服务器将返回 200 OK

提示:您可以取消选中“语法突出显示?”复选框,而不必手动复制 edit 链接。查询后,您将能够点击 XML 响应正文中的链接。

总结

AtomPub/Atom 发布协议Google Data API 的底层协议)和 OAuth 等技术有助于推动 Web 的发展。 随着越来越多的网站开始采用这些标准,我们开发者将成为赢家。打造爆款应用突然变得不再那么令人望而生畏。

如果您对 OAuth Playground 或将 OAuth 与 Google API 搭配使用有任何疑问或意见,请访问 G Suite API 和 Marketplace API 支持论坛

资源