validation用户使用omniauth和Facebook的轨道API?

我构build了一个Rails API,并成功构build了一个用户使用Omniauth Identity进行身份validation的方法。

我们只需从客户端发送auth / identity / callback,传入一个auth_key和密码。
服务器然后返回一个守门员令牌,然后用户从此使用门禁令牌来访问应用程序并识别他们自己。

这张图解释了这一点:

客户端服务器关系

我们现在希望从客户端实现Facebooklogin,但在理论和实践上都难以实现。

在一个带有Omniauth Identity的简单Rails应用程序中,您只需调用auth / facebook,但是如果我们在客户端中放置了一个链接,就会调用服务器,然后服务器就会logging:

INFO -- omniauth: (facebook) Request phase initiated.

该应用程序在Facebook中设置正确的ID和秘密,所以也许login提示返回到服务器?

虽然链接authentication,我感到困惑。 任何帮助感激地感谢!

在这里输入图像说明

我发现的最好的方法(在这个问题上被卡住一段时间后)是手动执行你的omniauth2(具体来说就是在我的情况下使用satellizer angular plugin)。

我会讨论Facebook的解决scheme,因为这是我的情况,但一切可能适用于任何其他供应商。

首先你必须知道omniauth2是如何工作的

  1. 客户端:打开一个popup窗口供用户进行身份validation。
  2. 客户:login(如有必要),然后授权应用程序。
  3. 客户端:成功授权后,popup窗口被redirect回您的应用程序。 用code (授权码)查询string参数

redirect返回url必须匹配您的前端应用程序url而不是后端url,它必须在您的facebook应用程序configuration中指定

  1. 客户端: code参数被发回到打开popup窗口的父窗口。
  2. 客户端:父窗口closurespopup窗口并使用code参数向backend/auth/facebook发送POST请求。
  3. 服务器: code授权码 )被交换为access token

这里详细描述如何从facebook开发者文档交换access-tokencode

  1. 服务器:使用步骤6中检索的access-token来检索用户的信息。 正如这里所记载的那样具有很好的视觉帮

  2. VOILA你有自己的用户,你可以合并/创build帐户/链接​​与其他oauth提供商/等。 但记住,用户可以撤销一些权限(如电子邮件 ,Facebook支持撤销一些权限)…


(足够的说话,给我看一些代码)

首先你必须添加HTTParty gem到你的Gemfile

 gem 'httparty' # Makes http fun again (http client) 

我已经添加了这个包含步骤(6,7和8)stream程的要点 ,这些步骤是最有问题的步骤,几乎没有logging在任何地方。

主要出口2主要方法:

 Omniauth::Facebook.authenticate(authorization_code) 

用于通过facebookauthentication用户并返回user_info,long_live_access_token(有效期为60天)

 Omniauth::Facebook.deauthorize(access_token) 

这是用来取消授权/撤销access_token和应用程序在Facebook上的权限…

这是用于特殊要求,我有,当用户撤销在Facebooklogin请求的电子邮件许可…我们撤销整个应用程序的权限…这将提示用户在下次login,就好像这是他的第一次login(不需要去facebook应用程序并手动撤销应用程序).​​..

这里是如何在控制器中使用的

 user_info, access_token = Omniauth::Facebook.authenticate(params['code']) if user_info['email'].blank? Omniauth::Facebook.deauthorize(access_token) end 

就是这样…现在如果你对实现的内部感兴趣的话,这里就是代码。 (添加参考)随意分叉,编辑它,帮助使其更好。

 require 'httparty' module Omniauth class Facebook include HTTParty # The base uri for facebook graph API base_uri 'https://graph.facebook.com/v2.3' # Used to authenticate app with facebook user # Usage # Omniauth::Facebook.authenticate('authorization_code') # Flow # Retrieve access_token from authorization_code # Retrieve User_Info hash from access_token def self.authenticate(code) provider = self.new access_token = provider.get_access_token(code) user_info = provider.get_user_profile(access_token) return user_info, access_token end # Used to revoke the application permissions and login if a user # revoked some of the mandatory permissions required by the application # like the email # Usage # Omniauth::Facebook.deauthorize(access_token) # Flow # Send DELETE /me/permissions?access_token=XXX def self.deauthorize(access_token) options = { query: { access_token: access_token } } response = self.delete('/me/permissions', options) # Something went wrong most propably beacuse of the connection. unless response.success? Rails.logger.error 'Omniauth::Facebook.deauthorize Failed' fail Omniauth::ResponseError, 'errors.auth.facebook.deauthorization' end response.parsed_response end def get_access_token(code) response = self.class.get('/oauth/access_token', query(code)) # Something went wrong either wrong configuration or connection unless response.success? Rails.logger.error 'Omniauth::Facebook.get_access_token Failed' fail Omniauth::ResponseError, 'errors.auth.facebook.access_token' end response.parsed_response['access_token'] end def get_user_profile(access_token) options = { query: { access_token: access_token } } response = self.class.get('/me', options) # Something went wrong most propably beacuse of the connection. unless response.success? Rails.logger.error 'Omniauth::Facebook.get_user_profile Failed' fail Omniauth::ResponseError, 'errors.auth.facebook.user_profile' end response.parsed_response end private # access_token required params # https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3#confirm def query(code) { query: { # The authorization_code we want to exchange for the access_token code: code, # This must match the redirectUrl registerd in the facebook app. # You can save it to ENV['WEB_APP_URL'] if you have multiple facebook apps for development and testing # so you can support testing app on development and production app on production env. redirect_uri: "http://localhost:9000/", client_id: ENV['FB_APP_ID'], # Facebook appId client_secret: ENV['FB_APP_SECRET'], # Facebook app secret (must not exist on front-end app for security) } } end end end 

这里是另一个nodejs教程实施oauth的instagram ,帮助我了解oauth2如何工作(添加为参考)

为了解决这个问题,我find的最好的资源是在卫星github回购轨道的示例应用程序: https : //github.com/sahat/satellizer/tree/master/examples/server/ruby

您的卫星代码调用AuthController.authenticate方法。 此方法使用每个提供程序的oauth模型类将您收到的代码转换为访问令牌。 然后在您的用户类中,您可以检索与您从提供者那里获得的信息相匹配的用户。

控制器方法最后将jwt令牌返回给客户端。

在我的情况下,控制器部分是有点不同,因为我也使用devise的邮件/密码authentication,但我复制th oauth类是原样,它的作品就像一个魅力。

与Facebook的API通信。 我build议使用'omniauth-facebook'gem 。 你可以克隆这个例子来了解更多: https : //github.com/ralphos/omniauth-facebook-example