无状态的RESTful API和第三方身份验证

9

我希望使用第三方身份验证(OpenID,可能是OAuth,但我猜OAuth是用于授权的),以便用户可以轻松登录。

但是,每次请求身份验证是否意味着我即使不需要来自第三方(例如Google)的任何东西也要多次调用它?例如,我使用OpenID身份验证,但我使用的API是一些内部的东西(例如/api/tasks/add)。


1
授权不等于认证。简而言之,在登录时,通常会对用户进行认证。在OAuth过程中,用户授权第三方访问其(或全部)帐户的某些部分。 - Alexandru Guzinschi
3个回答

9

首先,让我们解决理解问题。OpenID和OAuth有些不同。有一个简单的方法可以记住它们的区别:

  • OpenID用于人类使用。简单的例子:您想跳过无聊的注册步骤,让用户重复使用现有账户。
  • OAuth用于服务/机器人使用。简单的例子:您想让您的脚本通过一些用户数据访问外部API。

wikipedia提供了一个简单的解释:

请注意,对于OpenID,该过程始于应用程序请求用户的身份(通常是openid URI),而在OAuth的情况下, 应用程序直接请求受限制的访问OAuth Token (代客钥匙),以代表用户访问APIs (进入房屋)。 如果用户可以授予该访问权限,则应用程序可以使用APIs检索用于建立资料(身份)的唯一标识符。

enter image description here

所以,我想使用第三方身份验证...让用户可以轻松登录。可能意味着您将使用OpenID。

回答您的问题:您不需要在任何请求上调用任何第三方服务。这将非常低效和缓慢。OpenID提供程序将返回用户的凭据,然后您就可以开始了。

enter image description here

请确保您已正确识别需求。

好的,谢谢,现在我更好地理解了其中的一部分。在无状态应用程序中,我如何记住用户是谁?在像PassportJS这样的框架中,会返回一个UserProfile,我是否可以使用它?但这似乎不安全,任何人都可以获取此信息并像用户一样使用该应用程序? - Jiew Meng
是的,你说得对。存储原始数据可能有点危险。你可以将该信息作为加密的 blob 存储在客户端会话中,以避免频繁请求 OpenID 提供者,或使用基于 http://en.wikipedia.org/wiki/Cryptographic_nonce 的更复杂的协议。 - Renat Gilmanov

1

OpenID Connect是建立在OAuth2之上的身份验证机制。客户端获取了一个可以在每个请求中作为授权头部发送到资源服务器的承载令牌。

这个ID Token是由OpenID提供者签名的JWT。解码后的令牌长这样:

  {
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "exp": 1311281970,
   "iat": 1311280970
  }

因此,资源服务器可以验证它而无需联系OpenID提供者。 OpenID提供者具有用户端点,可在其中获取更详细的用户信息,例如姓名和电子邮件地址,这些信息未包含在令牌中。

1
我相信Renat Gilmanov和flup的回答对你有用,但我会尝试回答这个问题。
不,它并不意味着你在每次请求时都要联系第三方网站。实际上,你不能这样做,因为整个OpenID过程应该只在给定会话中发生一次(这对用户来说是一个有点烦人的手动步骤)。
我将把OpenID提供者(第三方)称为Google,因为这是你在问题中提到的例子。认证能为你做的唯一的事情就是给你Google的保证,即发出该特定请求的人也知道他们给你的Google账户名的密码。
之后,你需要跟踪来自同一“人”的请求,并将其视为同一帐户。基本上,无论你如何处理用户的其他“会话”信息,你现在可以假定此会话中的所有请求都来自该用户。
最常见的方法是立即向浏览器传递一个包含某些标识符的cookie,您在服务器上跟踪它,并确认传递给您该cookie的人也是知道该Google帐户密码的人。另一种选择是发送自定义HTTP头,这在某些方面更可取,但手动操作则更加棘手。
您可以手动构建所有内容,但我强烈建议找到一些库代码来尽可能多地为您处理此事。您没有提到使用什么构建此Web应用程序(实际上,您并没有明确表示它是Web应用程序,我只是从问题被标记的方式中推断出来),但几乎每个您可能使用的框架或系统都有很多选择。
从某种程度上讲,如果您正在编写用于连接到本机移动应用程序的API,则我编写的所有内容都是适用的。但是,由于某些OpenID提供者认为您是通过Web浏览器进入的,因此您可能必须跳过一些稍微复杂的步骤才能使用户进行身份验证。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接