使用 OAuth 1 玩转 OAuth

Avatar of Scott Fennell
Scott Fennell

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

这是关于使用 WP API 实现我称之为“远程控制 WordPress”的三部分系列文章中的第二篇,这是一种生活方式,您可以在“控制”安装中管理网络设置,并让其他“客户端”安装从控制端提取其设置。这样做的好处是,您可以集中在一个地方管理许多 WordPress 安装的设置。 第一篇文章 说明了如何将网络设置注册为 WP API 中的自定义端点,但没有演示如何在受权限回调保护时获取这些设置,而这些设置应该是受保护的。本文继续讨论该主题,演示如何将 OAuth 凭据传递给 WP API。

文章系列

第 1 部分: 用于远程控制 WordPress 的 WP REST API
第 2 部分: 使用 OAuth 1 玩转 OAuth(您现在所处位置!)
第 3 部分: 大规模远程控制 WordPress

OAuth 非常棘手。在学习这个过程时,我最初难以置信地发现它涉及的步骤数量和复杂程度。如果您像我一样,阅读 规范 是一个相当缺乏灵感的起点。 OAuth1 插件文档 非常出色,但在没有看到整个过程的情况下很难理解其中的细节。我希望为您提供一个可供您根据需要重构或修改的工作示例,让您了解不同步骤的运作方式。这样一来,您可以回过头来理解文档和规范中的要点。

本文所需内容

在第一篇文章中,我解释了我们需要两个 WordPress 安装才能实现这一点

  1. 控制安装
  2. 客户端安装

到目前为止,我们只使用了控制安装,但在这篇文章中,我们将同时使用两者。

我们还需要一些插件,我将在需要时指定。

与本系列的所有文章一样,我正在运行 twentysixteen 主题,尽管这实际上并不重要。

准备控制端

在第一篇文章中,我们在控制安装中安装了 WP REST API V2 插件。虽然该插件仍然是必要的,但请查看 /wp-json,它返回有关 API 的元数据。如果您 ctrl+f 搜索 oauth,则不会得到任何结果。

OAuth1 插件尚未在控制安装中激活。

OAuth?更像是 *无授权*,对吧?

咳咳。因此,现在是时候在控制端安装并网络激活 OAuth1 插件,然后再次尝试该 URL 了。瞧

OAuth1 插件已在控制安装中激活。

完美。控制端现在可以处理 OAuth 请求了。

OAuth1 插件做的另一件事是允许您注册应用程序,这正是我们的客户端安装所扮演的角色。在 wp-admin 中,查看 /wp-admin/users.php?page=rest-oauth1-apps 并注册您的客户端安装。您填写的详细信息并不重要——说真的,它们可以是乱码——但生成的 consumer_secretconsumer_key 至关重要。您稍后将需要它们。

OAuth1 插件的 wp-admin UI。

如果感觉我们是在插件上堆叠插件,我理解您的感受(如果您有兴趣,我曾在 其他地方 写过这种感觉)。不幸的是,这种情况只会变得更糟,所以请屏住呼吸,准备好迎接更多依赖项吧!

准备客户端

现在我们将切换到客户端安装,这是我们在本系列中第一次这样做。我的客户端安装碰巧是我的本地 MAMP。提醒一下,这确实是本文的全部目的:在生产环境中,您可能会有很多客户端安装。在现实生活中,我有大约 30 个,但对于这个演示,我只是使用我的本地 MAMP。

从 GitHub 获取我的 CSS-Tricks WP API Client 插件并网络激活它。它附带一个用于演示 oauth 请求的短代码:[css_tricks_wp_api_client meta_key='site_name']。将该短代码添加到页面的内容中。在这个示例中,我请求的是元键为 site_name 的设置的值。您可以在此处提供任何网络选项名称。

我们短代码的管理 UI。

您可以根据需要在前端浏览该短代码,但不要抱太大希望

是时候填写空白了。

这是您从 GitHub 下载插件,但随后必须硬编码一些您自己的值的情况。请注意主插件文件,您会在其中收到提示,要求您 填写空白。第一个是我们的 network_settings 端点的 URL,我们在本系列的第一篇文章中建立了该端点。其他四个用于 OAuth。

值得停下来重申一下我们为什么需要 OAuth。您可能还记得在本系列的 第一篇文章 中,这是由于 permission_callback,它只允许来自已认证用户的请求。这就是为什么我们需要在请求中提供 OAuth 标头,并且我们已将其设置到位,以便所有网络设置都不会公开供任何人查询。

因此,是时候构建一些 OAuth 凭据了。如果您像我一样,这就是您觉得令人困惑的部分;这就是您来到这里的原因。我无法更直白地说:准备好在进行 OAuth 时跳过一系列障碍。

Postman 满足您的需求

提供 OAuth 标头是一个复杂的过程,由于存在多种方法可以实现它,因此变得更加糟糕。

  1. 您可以使用 WP-CLI。 我自己还没有尝试过 本教程,但它看起来很有希望。
  2. 您可以编写大量代码并制作一个 非常酷的界面,该界面可在 Web 浏览器中直接使用。该 gist 让我了解了 OAuth 的本质。
  3. 您可以使用 HTTP 客户端,例如 Postman。我通过 本精彩教程 了解了如何使用 Postman 构建 OAuth 凭据。

我们将执行第三种方法(我主要是在重新整理该教程的一部分),因为它似乎是最简单的方法,因此请在您的计算机上下载并安装 Postman。安装 Postman 后,我们将向控制安装发送 HTTP 请求,如下所示

从 Postman 到控制安装的第一个 http 请求。

您需要填写那里的三个参数。其余参数由 Postman 生成,这实际上是使用 Postman 进行此练习的价值所在。您需要关注的三个值是

  1. URL。访问控制安装上的 /wp-jsonctrl+F 搜索“request”。您会找到一个类似于 http:\/\/example.com\/oauth1\/request 的 URL。复制、粘贴、取消斜杠,就可以使用了。
  2. 消费者密钥。您在教程前面在控制安装的 /wp-admin/users.php?page=rest-oauth1-apps 中生成了此密钥。在该 UI 中,它被称为“客户端密钥”,而不是“消费者密钥”,但这两个术语在此处是同义词。
  3. 消费者密钥。与步骤 2 相同,只是在 wp-admin 中它被称为“客户端密钥”,而不是“消费者密钥”。

Postman 将回复所谓的“临时凭据”,您需要从控制台复制这些凭据。我的看起来像这样

oauth_token=n33mdfL8TU5VP44pqxJffntL&oauth_token_secret=KRDKxqIpE7yratkW3LONQxgGDctaB4ieg73UKVyitSwp0GMY&oauth_callback_confirmed=true

“临时凭据”实际上只是一个查询字符串,您需要将其附加到一个特殊的 URL 上。与之前类似,浏览 wp-json,但这次查找 authorize URL。您需要将此 URL(以及一个问号)添加到 Postman 中的查询字符串前面,这将为您提供以下 URL

http://example.com/oauth1/authorize?oauth_token=n33mdfL8TU5VP44pqxJffntL&oauth_token_secret=KRDKxqIpE7yratkW3LONQxgGDctaB4ieg73UKVyitSwp0GMY&oauth_callback_confirmed=true

你永远也猜不到我们要拿这个 URL 干什么。把它输入到某个奇怪的 HTTP 应用里?现在还不会。把它通过某个奇怪的加密函数?不,先生。对着镜子念 13 遍吗?对于我们的用例来说,没必要。只需打开一个网页浏览器并访问它即可。我想你会很高兴的

控制安装上的 UI,用于授权你的客户端安装。

如果你当前没有登录到控制安装,你将首先被提示这样做。

点击授权后,你将获得一个令牌。

我们授权了客户端安装并获得了令牌。

如果你在控制安装上浏览你的用户资料(在 wp-admin 中),你现在将看到你已批准的应用列表,以及撤销它们的 UI

此用户已授权客户端安装。

将令牌带回 Postman 并发出以下请求

最终的 Postman 请求。

你需要提供五个参数。

  1. URL。wp-json 中,查找 access URL,并将我们刚刚获得的令牌作为 URL 变量添加到 oauth_verifier 中。换句话说,你的 URL 看起来会像这样

    http://example.com/oauth1/access?oauth_verifier=zDWqvZ4VNAd86wBWp6IJPKkV

    我如何为 URL 变量获得 oauth_verifier?我真的不知道。我运气好,在之前提到的教程的令牌交换部分看到了它。这似乎是需要做的事情。也许有几种方法可以实现此步骤。我在关于令牌交换的文档部分中没有看到任何关于将此值添加为 URL 变量的内容。但是,我发现如果你将 oauth_verifier 传递到请求的 body 中,它似乎也可以正常工作。随便吧?

  2. 消费者密钥。你在注册应用时在 wp-admin 中获得了它。它与你在之前的 Postman 调用中使用的值相同。
  3. 消费者密钥秘密。同样,你在注册应用时在 wp-admin 中获得了它。与消费者密钥一样,它与你在之前的 Postman 调用中使用的值相同。
  4. 令牌。这是在之前的 Postman 调用响应中找到的临时凭据。
  5. 令牌密钥秘密。这也是之前的 Postman 调用响应中的临时凭据。

Postman 将会返回你的 oauth_tokenoauth_token_secret。恭喜!我们现在拥有了进行 OAuth 认证的 HTTP 请求所需的一切!

返回客户端安装

在上一节中,我们收集了大量不同的令牌、密钥秘密、密钥,以及各种奇怪的东西。现在是时候将这些值投入使用。打开我的 CSS-Tricks WP API Client 插件的主插件文件,并按照源代码中指示的那样硬编码。

工作量很大,是的,但我们做到了!再次加载前端并查看生成的 JSON

甜蜜的胜利。

它成功了!我们刚刚从控制安装中检索了一个设置,在本例中为 site_name

当然,它在实践中有效,但在理论上有效吗?

通常我的学习方式是在深入研究示例之前先了解一些背景和理论。OAuth 不是那样的。它太奇怪了。这就是为什么我演示了一个示例,而没有提供任何理论。在 OAuth 方面,理论与实践的比例严重失衡。我认为我们大多数人在这里都可以阅读 codex 中的文章,并最终对我们正在做什么以及为什么这样做有一个大致的了解。OAuth 无法这样运作。至少对我来说是这样。

但我会告诉你我会做什么。请允许我将插件代码的几个部分映射到它们在 OAuth1 文档中的对应处理,以便你在实现 OAuth 时可以使用自己的批判性思维。

打开我的OAuth 类并阅读它。它有大量的注释。该类期望一个参数,即我们要查询的选项的 meta_key,并公开了一个函数 get_response(),用于进行 OAuth 认证的 HTTP 请求。构造函数调用了一系列函数,以便将你的密钥秘密和令牌转换为一个 auth 标头,我将对此进行深入探讨。

签名密钥

文档指示我们通过获取消费者密钥秘密和令牌密钥秘密,对每个密钥秘密进行 URL 编码,然后使用 & 将它们连接成一个字符串来构建签名密钥。我的函数正是这样做的。此值稍后将用于创建 OAuth 签名本身。

标头(第一次)

我们现在可以设置大多数 OAuth 标头,事实上,为了执行后续步骤,我们需要这样做。这是我的代码构建标头的方式。敏锐的读者会注意到,此函数稍后会在我们拥有签名后再次被调用。我稍后会重新讨论这个问题。但现在,我们准备好构建基本字符串了。

基本字符串

基本字符串是请求的每个部分的串联,包括 HTTP 方法、除签名之外的所有 OAuth 标头以及我们传递的任何变量。这是我的代码执行此操作的方式。与签名密钥一样,我们将在稍后使用基本字符串来创建签名。

签名

我们通过组合和散列基本字符串和签名密钥来创建签名。我的代码还通过 base64_encode() 运行它,这是必需的,但 PHP 的散列函数不会自动执行此操作。

标头(再次)

现在我们有了签名,我们可以将其添加到我们的OAuth 标头中。然后以非常特定的方式连接标头。最后,它们终于可以用于我们的get_response() 函数。当给控制安装打电话时,短代码调用此函数

一些挥之不去的担忧,也许?

我给你提供了一个可行的示例,并向你展示了我是如何得到这个示例的,但我觉得很糟糕。我真的没有解释大多数这些东西是什么。令牌、签名、密钥——老实说,我几乎无法跟踪所有这些。如果你真的需要知道它是如何工作的,我无法比规范做得更好。我此时对自己的教程失去了兴趣!这……嗯……超出了本教程的范围。祝你好运。

下一步是什么?

在第一篇文章中,我们向 WP API 添加了网络设置。在本文中,我们演示了如何检索它们。在第三篇也是最后一篇文章中,我们将探索我的抽象层,这样我们就不必在所有功能插件中重复整个过程,并且我们将编写一个小型功能插件作为如何使用该抽象的示例。

文章系列

第 1 部分: 用于远程控制 WordPress 的 WP REST API
第 2 部分: 使用 OAuth 1 玩转 OAuth(您现在所处位置!)
第 3 部分: 大规模远程控制 WordPress