使用 OAuth 2.0
最近我有机会研究 OAuth 2.0,我注意到OAuth 2.0 and OpenID connect
互联网上存在很多复杂性和混乱性。
其背后的原因是,这是一个难以理解的协议,有大量的术语和专业术语,并且网上有很多关于它的混淆。
当我开始了解 OAuth 2.0 和 OpenId 连接时,我没有找到一个单一的事实来源,并且有大量的博客,StackOverflow 上的每个人似乎都在以自己的方式解释它来实现它。
如果你曾经感到困惑、不知所措,那么你不是唯一一个,几乎每个人都有过这样的经历。在这篇博客里,我会尽量让事情变得不那么吓人,如果你觉得我的观点有道理,可以在评论区留言告诉我。
为什么我们有一个具体的规范,但对于如何使用它却有那么多不同的解释?像 HTTP 这样的协议不会发生这种情况,并且有一个非常正确和具体的使用方法,但对于 OAuth,在实现上存在一些模糊性,这使得它更加困难并且对如何使用它造成了混淆。
因此,在解释 OAuth 和 OpenId 之前,我只想为简单的登录和表单身份验证做好准备,这是网络上最基本的身份验证类型,用户输入用户名/电子邮件和密码,请求发送到服务器,服务器与数据库通信并验证用户名和密码,希望是散列的😉。
如果验证成功,服务器就会向 Web 浏览器发送一个 cookie 来跟踪用户。
现在业界正在远离这种自主研发的解决方案,这种简单的表单身份验证与 OAuth 无关,但我只是想让你知道这就是我们要比较的。
这种方法也有一些缺点,比如
- 安全
- 维护
由于您负责维护身份验证系统,因此只有您的服务器端代码会与数据库通信、验证密码等。您应该始终了解新的安全标准和最佳实践,例如哈希、加密和安全存储用户信息等。
让我们回到 2006-2007 年,当时的应用程序和网站也有几个用例,例如登录、身份验证、授权等,
因此我们可以将这些用例结合起来,称之为身份用例。
身份用例(2010 年之前)
- 简单登录(表单和 cookies)
- 跨站点单点登录 ( SAML )
- 移动登录(如果应用程序关闭,用户也应该保持登录状态
long living sessions
) - 委托授权(????)
这里的“委托授权”指的是 OAuth 协议的 Genesys。
虽然听起来很枯燥,但这正是我要重点讲解的内容。
您可能听说过委托授权,它每天都会用到,但您实际上并不知道它是什么。现在这是一种常见的模式,但十年前并非如此。
委托授权是我们允许特定网站访问我们的数据但不实际泄露凭证的过程。
所以当时没有好的方法来解决这个问题,一家名为 Yelp 的公司试图解决这个问题,但方法很糟糕,
在注册结束时,Yelp 会询问用户嘿,你想与你的 Gmail 或 Yahoo 联系人分享 Yelp 以进行注册或促销等,
为此,他们想要用户的实际 Gmail 电子邮件地址和密码,这意味着 Yelp 登录用户的 Gmail 帐户,抓取用户的联系人,向他们发送电子邮件,然后注销并扔掉密码,并承诺不做任何邪恶的事情😱
对于许多人来说,他们的 Gmail 或 Yahoo 帐户是他们的主要电子邮件帐户,也是他们所有信息(如银行详细信息、财务状况、密码重置等)的关键。因此,将他们的密码随意提供给任何应用程序或网站是一个非常糟糕的主意。
在这里,我并不是针对 Yelp 设计这种类型的解决方案,这只是一个很好的例子,用来说明问题是什么,以及他们为什么没有正确的方法来解决问题。
今天我们有了一个更好的方法来解决这个问题,使用 OAuth 协议,就像上图所示,Gitlab 想要访问 Github 用户信息。
现在我们将看到 Yelp 如何使用 OAuth 解决这个问题。
如今,我们几乎在每个应用程序上都有一个链接/按钮connect with google
,当用户单击此按钮时,用户将进入 OAuth 流程,最终结果是应用程序可以访问用户的授权信息。
用户可以确保想要访问联系人的应用程序只能访问联系人,而不能删除联系人、发送电子邮件或查看谷歌照片和驱动器信息上的照片等。
当用户点击connect with google
按钮时,浏览器将重定向到谷歌登录页面,account.google.com
这比以前的解决方案稍微好一点,因为用户向谷歌提供密码,而不是向 Yelp 或其他人提供密码。
假设现在用户登录成功,那么会出现一个提示,因为这个应用程序 Yelp 想要访问您的信息列表,其中包括您的公开个人资料或联系方式等,您确定要允许 Yelp 访问这些信息吗?
现在用户明确同意他们授予访问权限的任何内容,这很重要,这样他就不会被诱骗同意他不知道的事情。
因此,如果用户单击“否”,那么我们就不会做任何有趣的事情,并且流程将重新启动,但假设如果用户单击“是”,则浏览器将再次重定向回应用程序,回到它启动到应用程序中一个特殊位置的位置,称为回调或重定向回调或重定向 URI,我们将在博客的后面再次讨论。
然后,通过一点魔法,该应用程序(在我们的例子中是 Yelp)可以与其他 API 对话,比如谷歌联系人 API,而 Yelp 通常无法访问此 API,但现在它有一些东西(access_token
),当用户单击“是”按钮时,该应用程序会获得这些东西。
现在,下面是构成这个魔法的东西。
OAuth 2.0 术语
- 资源所有者
- 客户
- 授权服务器
- 资源服务器
- 授权授予
- 重定向 URI
- 访问令牌
资源所有者是一种谈论您和我作为单击“是”按钮并坐在计算机前拥有 Yelp 应用程序想要访问的数据的用户的奇特方式,在这种情况下,我是拥有 Gmail 帐户和联系人的资源所有者,Yelp 想要访问我的 Gmail 联系人。
客户端只是引用应用程序的一种方式,在这种情况下,Yelp 就是客户端,基本上是需要资源所有者数据的应用程序。
授权服务器是一个系统,资源所有者可以使用它来表示“是的”,“我授权了此权限”,并且“我授权了此操作”。在这种情况下,授权服务器就是accounts.google.com
。
如果你在谷歌上搜索“授权服务器”,你就会得到这样的结果😧!! 这就是为什么我写这篇博客,让事情更清晰一些。
资源服务器不同于授权服务器,资源服务器是保存客户端想要访问的数据的 API 服务器,在这种情况下,Google 联系人 API 是保存我的联系人的系统。
有时授权服务器和资源服务器会融合到同一个系统中,但很多时候它们是分开的。
OAuth 流程的整个要点是转到授权服务器,然后返回到客户端只是为了获得所谓的授权许可,而授权许可可以证明我已单击“是”或我同意此级别的权限或我允许您访问我的 Gmail 联系人。
当授权服务器重定向回客户端应用程序时,它需要知道重定向回哪里,这称为回调,有时称为重定向 URI,如果用户单击“是”,那么我应该在这个流程结束时到达哪里,然后他们接下来需要去哪里。
我上面提到过,授权是整个流程的重点,但在更高层次上,客户端真正需要的是一个叫做访问令牌的东西。
访问令牌是客户端用来访问资源服务器上用户授予访问权限或许可的任何数据的密钥。
呼,这么多信息,我想如果你读到现在,你肯定会感到困惑和不知所措,如果你愿意稍微耐心一点,你所有的疑虑和困惑都会很快消除。
让我们看一下我之前用所有这些术语描述的上面的图表。
现在我们将再次开始流程,我是客户网站 Yelp 上的资源所有者,我点击了connect with google
按钮,然后会发生什么呢?我将重定向到这个授权服务器,在本例中是 accounts.google.com,但它可能是 Facebook 授权服务器或由 Octa 托管的授权服务器,也可能是其他人的授权服务器。
在这个流程的开始阶段,当客户端重定向到授权服务器时,它已经传递了一些授权服务器所需的配置信息,所以它会告诉你,假设一切顺利,这里是我希望你在最后重定向回的 URI。所以我们必须在一开始就传递重定向 URI,并且还必须提供一些其他信息,例如我们想要什么类型的授权。
授权授予实际上有几种不同的类型,在这种情况下,我们将使用一种最简单的授权授予类型,称为代码授予或授权代码授予,因为我们正在请求代码,这称为授权代码流。
因此,现在授权服务器会提示登录,同意该权限,然后将所有好东西重定向回开头指定的位置,重定向 URI,并使用称为授权码的东西进行重定向,因为这就是我们在开始时要求的。
现在客户端无法使用该授权码做很多事情,事实上,客户端只能使用授权码做一件事,那就是再次返回授权服务器并与之交换此授权码access token
。
获取访问令牌后,客户端 Yelp 现在可以做他们最初希望我们做的事情,即前往资源服务器contacts.google.com
并请求用户联系人。
通常,资源服务器不允许访问用户的联系人,但在这种情况下,客户端在请求中附加了访问令牌,这证明用户表示资源服务器可以访问联系信息。
现在,如果客户端尝试做其他事情,比如不检索我的联系人而是删除我的所有联系人,在这种情况下,资源服务器会说你有一个访问令牌,但这并不意味着你可以做任何事情,用户只给了你对联系人的只读访问权限。
因此访问令牌授予客户端访问权限以执行特定操作,但客户端如何指定它想要执行的操作?
让我们添加一些术语。
- 范围
- 同意
授权服务器根据客户端需求具有范围列表,例如联系人的只读访问权限。
太多了,好的我明白了,让我们在下一篇博客中继续讨论范围和同意。
在Medium和Dev.to上关注我以了解更多有关技术的信息。
鏂囩珷鏉ユ簮锛�https://dev.to/tech_sam/introduction-to-oauth-2-0-1an2