passport.js RESTfulvalidation

如何使用passport.js处理身份validation(例如本地和Facebook),通过RESTful API而不是通过Web界面?

具体的问题是处理从callback到RESTful响应(JSON)的数据传递,使用典型的res.send({data:req.data}),设置redirect到Facebook的初始/login端点(/ login不能通过AJAX访问,因为它不是一个JSON响应 – 这是一个callback到Facebook的redirect)。

我发现https://github.com/halrobertson/test-restify-passport-facebook ,但是我很难理解它。

此外,passport.js如何存储auth凭证? 服务器(或是服务?)是由MongoDB支持的,我期望凭证(login和盐渍散列的pw)存储在那里,但我不知道passport.js是否有这种types的function。

这里提出了很多问题,看起来即使问题是在Node和passport.js的背景下提出的,但真正的问题更多的是关于工作stream程,而不是如何用特定的技术来实现这一点。

让我们使用@Keith示例设置,修改一下以增加安全性:

  • https://example.com Web服务器提供单个页面的Javascript客户端应用程序
  • https://example.com/api RESTful Web服务为富客户端应用程序提供服务器支持
  • 服务器在Node和passport.js中实现。
  • 服务器有一个“用户”表的数据库(任何种类)。
  • 用户名/密码和Facebook Connect作为authentication选项提供
  • 富客户端将REST请求发送到https://example.com/api
  • 可能有其他客户端(例如电话应用程序)使用https://example.com/api的Web服务,但不知道https://example.com的Web服务器。

请注意,我正在使用安全的HTTP。 这在我看来是公开的任何服务必须的,因为密码和授权令牌等敏感信息在客户端和服务器之间传递。

用户名/密码authentication

先来看看普通的旧authentication是如何工作的。

  • 用户连接到https://example.com
  • 服务器提供一个丰富的Javascript应用程序,呈现最初的页面。 有些人在页面上有一个login表单。
  • 由于用户没有login,所以这个单页面应用程序的很多部分还没有被填充数据。所有这些部分在“login”事件中都有一个事件监听器。 这一切都是客户端的东西,服务器不知道这些事件。
  • 用户input他/她的login名和密码,并点击提交button,这会触发一个Javascript处理程序来logging客户端variables中的用户名和密码。 然后这个处理程序触发“login”事件。 再一次,这是所有客户端操作, 凭据还没有发送到服务器
  • “login”事件的侦听器被调用。 其中的每一个现在都需要向https://example.com/api上的RESTful API发送一个或多个请求,以获取要在页面上呈现的用户特定数据。 他们发送给Web服务的每个请求都将包含用户名和密码,可能采用HTTP 基本authentication的forms,因为RESTful服务不允许将客户端状态从一个请求维护到另一个请求。 由于Web服务使用安全的HTTP,所以在传输过程中密码是安全encryption的。
  • https://example.com/api的networking服务收到大量个人请求,每个请求都带有身份validation信息。 每个请求中的用户名和密码都会根据用户数据库进行检查,如果发现正确,请求的函数将执行,数据以JSON格式返回给客户端。 如果用户名和密码不匹配,则以401 HTTP错误代码的forms将错误发送到客户端。
  • 而不是强迫客户端发送用户名和密码与每个请求,你可以有一个“get_access_token”函数在您的RESTful服务,采取用户名和密码,并回应一个令牌,这是一种encryption哈希是唯一的,有一些到期与之相关的date。 这些令牌与每个用户存储在数据库中。 然后客户端在随后的请求中发送访问令牌。 访问令牌将根据数据库而不是用户名和密码进行validation。
  • 非浏览器客户端应用程序(如电话应用程序)与上述相同,它们会要求用户input其凭据,然后在每次向Web服务请求时发送它们(或由它们生成的访问令牌)。

这个例子中重要的一点是, REST风格的Web服务需要对每个请求进行authentication

在这种情况下,附加的安全层将除了用户身份validation之外还添加客户端应用程序授权。 例如,如果您有Web客户端,iOS和Android应用程序都使用Web服务,则您可能希望服务器知道给定请求的三个客户端中的哪一个,而不pipe经过身份validation的用户是谁。 这可以使您的Web服务将某些function限制到特定的客户端。 为此,你可以使用API​​密钥和秘密,看到这个答案的一些想法。

Facebook身份validation

上面的工作stream程不适用于Facebook连接,因为通过Facebooklogin有第三方,Facebook本身。 login程序要求用户redirect到Facebook的网站,在该网站上input的凭据不在我们的控制范围之内。

那么让我们看看事情如何改变:

  • 用户连接到https://example.com
  • 服务器提供一个丰富的Javascript应用程序,呈现最初的页面。 有些人在页面中有一个包含“使用Facebooklogin”button的login表单。
  • 用户点击“使用Facebooklogin”button,这只是一个redirect到(例如) https://example.com/auth/facebook
  • https://example.com/auth/facebook路由由passport.js处理(请参阅文档 )
  • 所有用户看到的是页面变化,现在他们在Facebook托pipe页面,他们需要login和授权我们的Web应用程序。 这完全在我们的控制之外。
  • 用户login到Facebook并授予我们的应用程序权限,因此Facebook现在redirect到我们在passport.js设置中configuration的callbackURL,该文档中的示例在https://example.com/auth/facebook/callback
  • https://example.com/auth/facebook/callback路由的passport.js处理程序将调用接收Facebook访问令牌的callback函数以及来自Facebook的一些用户信息,包括用户的电子邮件地址。
  • 通过电子邮件,我们可以将用户定位到我们的数据库中,并使用它存储Facebook访问令牌。
  • 您在Facebookcallback中所做的最后一件事是redirect回到富客户端应用程序,但这次我们需要将用户名和访问令牌传递给客户端,以便它可以使用它们。 这可以通过多种方式来完成。 例如,可以通过服务器端模板引擎将JavaScriptvariables添加到页面,否则可以使用此信息返回cookie。 (感谢@RyanKimber指出了在URL中传递这些数据的安全问题,正如我最初的build议)。
  • 所以,现在我们再次启动单页面应用程序,但客户端拥有用户名和访问令牌。
  • 客户端应用程序可以立即触发“login”事件,并让应用程序的不同部分从Web服务请求他们需要的信息。
  • 所有发送到https://example.com/api的请求都将包含用于身份validation的Facebook访问令牌,或者通过REST API中的“get_access_token”函数从Facebook令牌生成的应用程序自己的访问令牌。
  • 非浏览器应用程序在这里有一些困难,因为OAuth需要Web浏览器login。要从手机或桌面应用程序login,您需要启动浏览器来redirect到Facebook,更糟糕的是,您需要一种方式让浏览器通过某种机制将Facebook访问令牌传递回应用程序。

我希望这回答了大部分问题。 当然,您可以用Twitter,Google或任何其他基于OAuth的身份validation服务replaceFacebook。

我有兴趣知道是否有人有一个更简单的方法来处理这个问题。

我非常感谢Miguel在每种情况下的完整stream程,但是我想在Facebook身份validation部分添加一些内容。

Facebook提供了一个Javascript SDK ,您可以直接在客户端获取访问令牌,然后将其传递到服务器,并用于从Facebook进一步提取所有用户信息。 所以你基本上不需要重新指导。

而且,对于移动应用程序,也可以使用相同的API端点。 只需使用Facebook的Android / iOS SDK,在客户端获取Facebook access_token并将其传递给服务器。

关于无状态性质,如get_access_token用于生成令牌并传递给客户端时,该令牌也存储在服务器上。 所以它和会话标记一样好,我相信这会使其成为有状态的?

只是我2分钱..

这是一篇非常棒的文章,我发现它可以帮助你进行身份validation:

  • Facebook的
  • 推特
  • 谷歌
  • 本地身份validation

易节点身份validation:设置和本地