我发现最好的方法(在遇到这个问题一段时间后)是手动进行Omniauth2认证(特别是在我的情况下使用satellizerangular插件)...
我将讨论Facebook的解决方案,因为这是我的情况,但所有内容都适用于任何其他提供商。
首先,您需要了解Omniauth2的工作方式(如此文档化...)
- 客户端:打开弹出窗口以供用户进行身份验证。
- 客户端:登录(如果必要),然后授权应用程序。
- 客户端:成功授权后,弹出窗口将重定向回您的应用程序,并带有
code
(授权代码)查询字符串参数
重定向返回的URL必须与您的前端应用程序URL匹配,而不是后端URL,并且必须在您的Facebook应用程序配置中指定
4.
客户端:将
code
参数发送回打开弹出窗口的父窗口。
5.
客户端:父窗口关闭弹出窗口,并向
backend/auth/facebook
发送
POST
请求,其中包含
code
参数。
6.
服务器:code
(
授权码)被交换为
访问令牌
。
这里详细描述了如何从Facebook开发者文档中用code
交换access-token
。
服务器:使用在步骤6中检索到的access-token
来检索用户信息。
完成了,您已经拥有一个可以合并/创建帐户/与其他oauth提供商链接等操作的用户。但请注意,用户可能会撤销某些权限(例如电子邮件,Facebook支持撤销某些权限)...
首先,您需要将HTTParty gem添加到您的Gemfile中。
gem 'httparty' # Makes http fun again (http client)
我已经添加了
这个代码片段,其中包含第6、7和8步的流程,这些步骤是最棘手的,并且几乎没有文档记录。
这个代码片段导出了2个主要方法:
Omniauth::Facebook.authenticate(authorization_code)
此功能用于通过 Facebook 认证用户并返回用户信息、长期访问令牌(有效期为 60 天)
Omniauth::Facebook.deauthorize(access_token)
这是用于在Facebook上取消授权/撤销access_token和应用程序权限的特殊需求...
当用户在Facebook登录时撤销了请求的电子邮件权限时,我们会撤销整个应用程序的权限...这将在下次登录时提示用户,就像这是他的第一次登录一样(无需转到Facebook应用程序并手动撤销应用程序)...
以下是控制器中的使用方法
user_info, access_token = Omniauth::Facebook.authenticate(params['code'])
if user_info['email'].blank?
Omniauth::Facebook.deauthorize(access_token)
end
就是这样...如果你对实现的内部感兴趣...这里是在gist中看到的代码。(供参考添加)
请随意fork它,编辑它,帮助使它变得更好。
require 'httparty'
module Omniauth
class Facebook
include HTTParty
base_uri 'https://graph.facebook.com/v2.3'
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
def self.deauthorize(access_token)
options = { query: { access_token: access_token } }
response = self.delete('/me/permissions', options)
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))
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)
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
def query(code)
{
query: {
code: code,
redirect_uri: "http://localhost:9000/",
client_id: ENV['FB_APP_ID'],
client_secret: ENV['FB_APP_SECRET'],
}
}
end
end
end
这里有另一篇Node.js教程,演示如何为Instagram实现OAuth,帮助我理解了OAuth2的工作原理(仅供参考)
omniauth-facebook
gem 吗?https://github.com/mkdynamic/omniauth-facebook - CDub