OmniAuth on Rails

How to simplify signing in to a Ruby on Rails application by using accounts people already have


There is a lot of information out there about adding a “Sign in with Facebook” button to various types of websites, but a lot of that information is confusing to follow.

This post provides a step-by-step guide to adding “Sign in with …” buttons for a recent Ruby on Rails application using Devise for user authentication. These sign in buttons use a technology called OmniAuth (OAuth for short).

The sign in page with logos

If you are building a small application, you may want to help your users not having to remember an additional password by using only OmniAuth.

The code for the demo app is available on GitHub at https://github.com/monkbroc/omniauth-demo

Here’s the final result

Creating the application

Start a new Rails application

rails new omniauth_demo

Add OmniAuth and a couple providers to the Gemfile

# User account management
gem 'devise', '~> 3.4'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
gem 'omniauth-linkedin-oauth2'
gem 'omniauth-twitter'
# To manage environment variables locally
gem 'dotenv'

Install the new gems

bundle install

Create a User model that can only be authenticated with OmniAuth

rails generate devise:install
rails generate devise User

The User model

This is the User model.

app/models/user.rb

Notice that the User model doesn’t have :database_authenticatable so the user won’t have a password inside this application.

The :developer OmniAuth provider is used to sign in during development. It simply asks for a name and email (no password) and logs in with that email. It is necessary because OmniAuth doesn’t work on a development machine, only on the production server because of the callback URLs (see below).

This is the migration to create the user

db/migrate/20150218161640_devise_create_users.rb

Run the migrations to create the users table

rake db:migrate

Signing up for OAuth credentials

You’ll need to have an “application” created on Facebook, LinkedIn, Twitter, Google and any other OmniAuth provider you want to use for your users to sign in.

Create an application on Facebook

Go to https://developers.facebook.com/apps and create a new Web app. You can skip the Quick Start.

Fill in Site URL and App Domains. You’ll also need to copy the App ID and App Secret for use later.

In the Advanced tab, make you need to add the callback URL to your application. It is your app site, followed by /users/auth/facebook/callback

You can also go to App Details to select a logo that will be displayed when a user signs in with Facebook toyour app.

Make sure to mark your app live in Settings when you are ready, otherwise only you (the app creator) will be able to sign in.

Create an application on LinkedIn

Go to https://www.linkedin.com/secure/developer and add a new application.

The important field to fill in is the OAuth 2.0 Redirect URLs. It is your app site, followed by /users/auth/linkedin/callback

You can also put a URL to a logo that will be shown to users signing in to your app with LinkedIn.

After you click Create application, make sure you grab the API Key and Secret Key.

Create an application on Twitter

Go to https://apps.twitter.com/ and create a new app.

Make sure you set the callback URL to your app site, followed by /users/auth/twitter/callback, and check “Allow this application to be used to Sign in with Twitter”

After creating the app, in the Settings tab you can add a logo.

In the Keys and Access Tokens tab, grab the API key and API secret.

Create an application on Google

Go to https://console.developers.google.com and click Create Project.

In the APIs section, enable the Google+ API and the Google Contacts API. Without this, signing in with Google will fail with the error “Could not authenticate you from GoogleOauth2 because Invalid credentials.”

From the Credentials section, click Create new Client ID and select Web application.

In the next steps, the important setting is again setting the callback URL to to your app site, followed by /users/auth/google_oauth2/callback (it has to be google_oauth2 because of the omniauth-google-oauth2 gem)

Copy the Client ID and Client Secret for later.

Adding OmniAuth API Keys and Secret to the Rails application

Finally we can add the keys we generated above to the Rails application.

For development, store the keys in the .env file at the root of the Rails application. Make sure the .env file is not checked in to git.

.env

We add all the OmniAuth providers configured in the User model to the Devise initializer

config/initializers/devise.rb

Configuring routes and controllers

We need to add the OmniAuth controller to the Rails router. Also, since we don’t have :database_authenticatable in the User Devise configuration, we need to manually define the sign_in and sign_out routes.

config/routes.rb

The callback controller provides the endpoints that we used above while configuring Facebook, LinkedIn, Twitter and Google. It finds or creates a user based on the provider and signs them in.

app/controllers/users/omniauth_callbacks_controller.rb

Configuring views

All that is left is to add the sign in/sign out button to the application layout and to add the OmniAuth provider logos on the sign in page.

app/views/layouts/application.html.erb
app/views/devise/sessions/new.html.erb

The important piece here is to have the link to omniauth_authorize_path for each of the providers.

Deploy to the cloud

To see this in action, you have to deploy to a public webserver.

An easy solution is to use Heroku.

Make sure the app is under version control

git init
git add -A
git commit -m "Initial version"

Create a Heroku application

heroku apps:create omniauth-demo

Add the OmniAuth API Keys and Secrets to the Heroku application. Don’t forget this step.

heroku config:set FACEBOOK_API_KEY=XXXXXXXXXXXXXXXX FACEBOOK_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX LINKEDIN_API_KEY=XXXXXXXXXXXXXX LINKEDIN_API_SECRET=XXXXXXXXXXXXXXXX TWITTER_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXX TWITTER_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GOOGLE_OAUTH2_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX GOOGLE_OAUTH2_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXX

Deploy!

git push heroku
heroku run rake db:migrate

Trying it out

If you got all the way down here, congratulations! Thanks for reading.

Go try it out yourself at https://omniauth-demo.herokuapp.com

Check out the demo app at https://github.com/monkbroc/omniauth-demo and add OmniAuth to your app today!

Julien Vanier

If you have problems making this work, reach out to me on Twitter @monkbroc

Julien Vanier, CTO of MuniRent

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.