我正在构建一个带有Rails后端的iPhone客户端。客户端通过Oauth2 API与服务器通信。我使用oauth2和门卫宝石来设置它。
必须使用令牌发送每个API请求。我目前支持两种令牌“类型”:
这一切都运转良好,但我现在遇到一个问题,我允许用户也使用Facebook登录应用程序。
用户登录FB后,我的客户端通过将Facebook UID传递到我的服务器(使用客户端令牌)进行响应。然后,我在服务器上进行一些检查,以将此UID与我数据库中的现有用户进行匹配。
问题在于:我想用用户令牌回复此请求。当用户现在将登录到应用程序时,需要此令牌,并且任何后续请求都将需要此令牌。但是,目前我觉得我这样做的唯一方法是:
回复用户名和密码。然后让客户端在密码凭据流之后请求用户令牌。我不喜欢这个,因为我传递了一个密码,它需要多次旅行。
我觉得我可能会遗漏一些基本的东西。还有另一种方法我应该处理这个流程吗?
答案 0 :(得分:1)
我想我有一个解决方案,但这绝对是一个黑客攻击。
基本上我劫持密码凭证流程也处理这个Facebook场景。
客户端像这样进行调用(格式化可能在我在ruby中测试时关闭):
curl -i http://www.example.com/oauth/token -F grant_type=password -F client_id=(client id)-F client_secret=(client secret) -F username=(email address) -F password=(password) -F provider="facebook" -F uid=(fb uid) -F token=(fb token)
在我的服务器上,我检查“provider”参数。如果找到,则使用facebook uid代替密码身份验证在用户表中查找匹配项。我还传递FB令牌作为安全措施(我在查找匹配之前验证此令牌属于uid)。如果找到匹配项,则将用户设置为令牌的资源所有者,这意味着我最终得到了用户令牌。
这是来自我的doorkeeper.rb的代码块:
resource_owner_from_credentials do |routes|
if params[:provider]
// FB uid authentication path code here
else
// password authentication
user = User.find_by_email(params[:username])
user if user && user.authenticate(params[:password])
end
end
答案 1 :(得分:0)
OAuth 2.0定义的资源所有者密码凭据类型并不真正适合外部登录,例如Facebook,因为身份验证是通过外部站点完成的,而不是来自您自己的授权服务器上的用户名和密码。
一种解决方案是切换到OAuth 2.0的隐式授权类型(http://tools.ietf.org/html/rfc6749#section-4.2)。门卫也支持这种类型。
从您的应用程序中,您必须打开Web视图并将用户重定向到Doorkeeper的授权端点(默认值:/ oauth / authorize),其参数为:client_id = ...,redirect_uri = ...和response_type = token 。此外,您必须告诉Doorkeeper将用户重定向到FB登录。
因此请将此添加到doorkeeper.rb:
resource_owner_authenticator do
user_from_session || begin
session[:return_to] = request.fullpath
fb_login_url = "..." # add here your facebook login url
redirect_to(fb_login_url)
end
end
用户通过FB登录并验证服务器上的用户后,您必须将用户重定向回会话[:return_to]指向/ oauth / authorize的内容,并重定向到最初给定的redirect_uri,包括access_token在网址中。