3

我正在构建一个带有 Rails 后端的 iPhone 客户端。客户端通过 Oauth2 API 与服务器通信。我已经使用 oauth2 和 doorkeeper gems 进行了设置。

每个 API 请求都必须使用令牌发送。我目前支持两种令牌“类型”:

  • 客户端:使用客户端凭据授予类型。这适用于非用户特定的请求,例如访问应用程序范围的资产、密钥等。
  • 用户:使用密码凭据授权类型。要获取此令牌,客户端必须通过传递有效的用户名/密码组合来请求它。所有用户请求都使用此令牌。

这一切正常,但我现在遇到了一个问题,因为我允许用户也使用 Facebook 登录应用程序。

在用户登录 FB 后,我的客户端通过将 Facebook UID 传递给我的服务器(使用客户端令牌)进行响应。然后,我在我的服务器上进行一些检查,以将此 UID 与我数据库中的现有用户相匹配。

这是问题所在:我想使用用户令牌响应此请求。需要此令牌,因为用户现在将登录到应用程序,并且任何后续请求都将需要此令牌。但是,目前我觉得我这样做的唯一方法是:

回复用户名和密码。然后让客户端按照密码凭证流程请求用户令牌。我不喜欢这样,因为我要传递密码,而且它需要多次旅行。

我觉得我可能缺少一些基本的东西。我应该有另一种方式来处理这个流程吗?

4

2 回答 2

1

我想我有一个解决方案,但它绝对是一个 hack。

基本上我正在劫持密码凭据流来处理这个 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)

在我的服务器上,我检查“提供者”参数。如果找到,它会使用 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
于 2012-12-06T01:38:03.743 回答
0

OAuth 2.0 定义的资源所有者密码凭证类型实际上并不适合外部登录,例如 Facebook,因为身份验证是通过外部站点完成的,而不是来自您自己授权服务器上的用户名和密码。

一种解决方案是切换到 OAuth 2.0 的隐式授权类型 ( https://www.rfc-editor.org/rfc/rfc6749#section-4.2 )。Doorkeeper 也支持这种类型。

从您的应用程序中,您必须打开一个 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 登录并在服务器上对用户进行身份验证后,您必须将用户重定向回 session[:return_to] 指向 /oauth/authorize 的内容,并重定向到最初给定的 redirect_uri,包括 url 中的 access_token .

于 2014-11-14T16:01:31.847 回答