我这几天一直在绞尽脑汁,试图找出如何将用户名/密码身份验证添加到我的 Rails 移动 API 中。
以下是我当前身份验证流程的简要概述:
用户在手机客户端、客户端选择“用Facebook登录” 重定向到 Facebook 应用程序并请求 access_token
成功后,Facebook 会使用访问令牌和客户端进行响应 重定向回我的应用程序。
客户端将访问令牌发送到我的API
我的 API 使用 koala gem 来检查访问令牌是否有效。
如果令牌有效,Facebook 会将用户数据发送到 API 创建新用户的地方。如果用户已经存在,我的 API 会发送用户数据。
我的 API 在步骤 4 中处理访问令牌,如下所示:
def self.authenticate_user_from_facebook(fb_access_token)
user = User.new
graph = Koala::Facebook::API.new(fb_access_token)
profile = graph.get_object('me')
#user['fb_id'] = profile['id']
#user['fb_token'] = fb_access_token
# Generate user hash
uhash = Hash.new
uhash['provider'] = 'facebook'
uhash['uid'] = profile['id']
uhash['info'] = Hash.new
uhash['info']['nickname'] = profile['username']
uhash['info']['name'] = profile['name']
uhash['info']['email'] = profile['email']
uhash['info']['first_name'] = profile['first_name']
uhash['info']['last_name'] = profile['last_name']
uhash['info']['verified'] = profile['verified']
uhash['info']['urls'] = Hash.new
uhash['info']['urls']['Facebook'] = profile['link']
uhash['credentials'] = Hash.new
uhash['credentials']['token'] = fb_access_token
uhash['extra'] = Hash.new
uhash['extra']['raw_info'] = Hash.new
#Save the new data
user = User.apply_auth(uhash)
return user
end
def self.apply_auth(uhash)
User.where(:uid => uhash['uid'], :provider => uhash['provider']).first_or_create do |user|
user.provider = uhash['provider']
user.uid = uhash['uid']
user.nickname = uhash['info']['nickname']
user.email = uhash['info']['email']
user.name = uhash['info']['name']
user.first_name = uhash['info']['first_name']
user.last_name = uhash['info']['last_name']
end
end
创建用户后,他们可以使用其访问令牌向我的 API 发出请求,如下所示:
在步骤 2 中,API 使用 koala 来验证用户访问令牌。这是通过将以下 before_filter 应用于所有控制器来完成的。
before_filter :current_user
在我的 application_helper.rb 中
def current_user
@current_user ||= User.authenticate_user_from_facebook(params[:access_token])
end
每次用户向我的 API 发出请求时,都会使用 koala gem 检查令牌是否有效,然后处理该请求。
我现在尝试添加的是仅使用用户名和密码的身份验证。
我研究过的事情
我一直在不断参考 Railscast 235、209、250、82 并阅读 OAuth2。我对身份验证的工作原理有基本的了解,但我无法将其应用到当前的身份验证流程中。
设计令牌认证 参考 Railscast 235、209 和这篇博文: http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/
我可以了解如何登录和验证使用用户名和密码登录的用户。然而,我很困惑这将如何与我的 Facebook 登录流程相结合。我不明白如何为已经拥有 Facebook 生成的访问令牌的用户创建会话。
OAuth2 让我的 API 成为 OAuth2 提供程序似乎是一个好方法,但重定向到浏览器似乎有点愚蠢,而且我不知道是否可以从浏览器重定向回我的应用程序。
从头开始进行身份验证 这是我正在考虑的选择,但我会重新发明轮子。
如有任何建议,我们将不胜感激!
您可能想调查一下Warden。无论您使用令牌、密码还是 Facebook,Warden 都可以轻松设置和使用不同的身份验证策略。它是基于 Rack 的,因此它也可以在 Rails 之外工作,如果您想使用 Grape 之类的 API 的话,这是很好的选择。
这是Warden 上的RailsCast。 (需要专业版订阅)