Rails API:使用用户名/密码或facebook令牌从本机移动应用程序验证用户

Jer*_*ers 12 api rest ios oauth-2.0 omniauth

所以我现在已经把头发拉了几天,试图弄清楚如何在我的rails mobile API中添加用户名/密码验证.

以下是我当前身份验证流程的简要概述:

在此输入图像描述

  1. 用户在移动客户端上选择"使用Facebook登录",客户端重定向到Facebook应用程序并请求access_token

  2. 成功时,Facebook使用访问令牌进行响应,客户端重定向回我的应用程序.

  3. 客户端将访问令牌发送到我的API

  4. My API uses the koala gem to check if the access token is valid.

  5. If the token is valid, Facebook sends the users data to the API where a new user is created. If the user already exists, my API sends down the users data.

My API handles the access token in step 4 as shown below:

      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
Run Code Online (Sandbox Code Playgroud)

Once the user is created, they can make requests to my API using their access token as shown below:

在此输入图像描述

In step 2 the API is using koala to verify the users access token. This is done by applying the following before_filter to all controllers.

before_filter :current_user
Run Code Online (Sandbox Code Playgroud)

and in my application_helper.rb

def current_user
    @current_user ||= User.authenticate_user_from_facebook(params[:access_token])
end
Run Code Online (Sandbox Code Playgroud)

Every time a user makes a request to my API the koala gem is used to check if the token is valid, then the request is processed.

What I am trying to add now is authentication with only username and password.

Things I have looked into

I have been constantly referring to Railscast 235, 209, 250, 82 and reading up on OAuth2. I have a basic understanding of how authentication works but Im having trouble applying it to my current authentication flow.

Devise Token Authentication Referring to Railscast 235, 209, and this blog post: http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/

I can understand how to login and validate a user who logs in with a username and password. However I am confused as to how that will mesh with my Facebook login flow. I do not understand how to create a session with devise for a user who already has an access token generated by Facebook.

OAuth2 Making my API an OAuth2 provider seems like it would be a good way to go, but it seems kind of silly to redirect to a browser, and I don't know if its possible to redirect back from the browser to my app.

Authentication From Scratch This is the option I am thinking of going with but I would be reinventing the wheel.

Thanks for reading this long post! Any advice is appreciated!

小智 1

你可能想调查一下典狱长。无论您使用令牌、密码还是 Facebook,Warden 都可以轻松设置和使用不同的身份验证策略。它是基于 Rack 的,因此它也可以在 Rails 之外工作,如果您想使用 Grape 之类的 API 的话,这是很好的选择。

这是Warden 上的 RailsCast。(需要专业版订阅)