Facebook Authentication for Rails APIs

I’ve implemented Facebook login plenty of times on the Android side of things but I have never implemented on on the API side.

Granted, yes, I’ve implemented Facebook OAuth when building Ruby on Rails applications, but have never implemented one when building out an API that’s supposed to take in a Facebook access token from the client side and then retrieve user information with it to sign in or register a new user.

When implementing Facebook OAuth (or Google, Twitter, etc.), I usually just default to OmniAuth and rely on the various oauth strategy plugins written for the gem. Unfortunately, the OmniAuth gem’s default behavior doesn’t lend itself well to integrating it to build oauth systems within an API. Thus, we need a different and a much more simple solution.

Enter the koala gem. I’ve always known of its existence and have used it at times, but never thought that it would be useful for using a Facebook access token to retrieve user profiles. Using the gem to implement Facebook authentication for your Rails API is incredibly simple. Let’s say that you have a User model that you need to sign in or create using Facebook access tokens that may be passed into your API via the mobile devices. Also, let’s say that you have a controller called FacebookAuthenticationsController whose sole purpose is to take in a facebook_access_token and retrieve or create a user using the token. First, let’s write the controller that will take in the token.

The create method takes in a facebook_access_token and tries to find or create a User using the token. If the user has persisted, meaning that the User is persisted (or existing) in the database, then we return the user data. If not, we return what caused the user errors. If you’re familiar with ActiveRecord, you’ll quickly notice that find_or_create_with_facebook_token is not an ActiveRecord method. ActiveRecord methods use the term “by” rather than “with”, so the ActiveRecord’s version of the method goes like User.find_or_create_by_facebook_token.

Our users table in our schema.rb looks like the following.

Notice that I’m using devise (although it’s completely unimportant to this post). The important columns in the users table for this facebook login/registration implementation are: name, picture_url, uid, provider, and oauth_token. Now, let’s get to writing ourfind_or_create_with_facebook_token method in our User model.

In our method, we use the oauth_access_token along with the Koala gem to retrieve the user graph from Facebook. We retrieve the profile data from the graph and then store necessary data in a hash. We then use the uid (which really is the Facebook user id) to try to find whether the user exists in the database. If the user exists, we update the user attributes and return that user and if the user does not exist, we create a new user using the data that we retrieved from Facebook. The reason uid is important here is because while the oauth_access_tokens will eventually expire and change, the uid from Facebook does not. Thus we use that attribute to check whether we already have the user in our database or not.

Simple yes? I like this method especially if you’re building an API that will solely rely on Facebook Login for authentication because you don’t have to add larger dependencies like devise, oauth, and etc.