The majority of Ruby on Rails applications require registration and authentication mechanisms, building them from scratch requires time effort and precision, and if not done right it can expose your application to security breaches, thankfully there is Devise. This gem is so flexible and versatile that you can set up a really robust and powerful authentication system within minutes.
One great way to make our users love our applications it’s allowing them to access our application without creating a new account, honestly, that sucks! people don’t want to create more and more accounts, they already have too many.
Omniauth allows you to easily integrate more than sixty authentication providers, including Facebook, Google, Twitter and GitHub. In this tutorial, I’m going to explain how to integrate these authentication providers into your app.
Step 1 – Create a New Rails App
For the purpose of this tutorial, we are going to call our new app omniapp. After creating the application, use cd to enter the application’s base directory.
rails new blogapp
cd blogapp
Note: All commands must be run from inside of your applications directory.
Step 2 – Add Gems to your Gemfile
As I mentioned before omniAuth supports several providers, for this exercise we are going to use one of the most popular ones, facebook, therefore we need to add ‘omniauth-facebook’ gem to our gem file.
#Gemfile gem 'devise' gem 'omniauth-facebook'
You will need similar gems to support other providers. For example, to support Twitter, you will need omniauth-twitter.
Now run bundle install
to install the new gems.
Step 3 – Add Functionality to your App
In order to test what we are doing, we will need to see if our app is working, so let’s add basic functionality to our blog app. We can use rails g scaffold for that.
Pro Tip: Try not to use rails g scaffold that much, since this generator may add things you dont really need and will make your app slower.
But to make our process faster let’s use it:
rails g scaffold Post title:string description:string
rake db:migrate
Let’s edit our routes and add our root by going into /config/routes.rb
.
Rails.application.routes.draw do resources :posts root 'posts#index' end
Now you can start your development server by typing rails s
, and visit http://localhost:3000/ from your browser.
Feel free and add a couple of posts by clicking “New Post”, make sure your application is working. As you can see, no login is required yet, let’s fix that!
Step 4 – Configure Devise
Type the following commands to add Devise authentication support.
rails generate devise:install
rails generate devise User
rake db:migrate
This adds the sign-in and sign-up forms, and all the associated logic.
Now we have a basic authentication system, where users can register, and then log in. However, all the pages are still directly accessible. To change this, edit blogapp/app/controllers/application_controller.rb
and add authenticate_user!
as an action that has to be performed before rendering any view.
class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :authenticate_user! end
You can register as a new user by visiting http//:localhost:3000/users/sign_up
.
Go ahead and create one!
Step 5 – Add OmniAuth Capability to User Model
Add a new column called uid to the model that Devise generated.
rails g migration AddOmniauthToUsers provider:index uid:index
rake db:migrate
Step 6 – Add OmniAuth Configuration to initializer
Go into config/initializers/devise.rb
and under the omniAuth section add:
config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET']
This requires that you have FACEBOOK_KEY
and FACEBOOK_SECRET
in your environment. Create an application in the facebook developer console and get these values from there.
You will be asked for a callback URL during the registration process, here you can add http://localhost:3000/users/auth/facebook/callback
. This setting is listed under Client OAuth Settings in the dashboard.
Set the values in your shell like so,
export FACEBOOK_KEY=your_app_id
export FACEBOOK_SECRET=your_app_secret
Remember never to keep your API Keys visible in your application, it’s not safe, you can use different gems to protect them, I like to use figaro gem for that.
Step 7 – Enable a Route for Omniauth
Add this to routes.rb
to tell create a route for Omniauth to send its authentication data to:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
Step 8 – Enable Omniauth for User Model
Add this line to user.rb
devise :omniauthable, :omniauth_providers => [:facebook]
We have to write a User.from_omniauth
method ourselves.
class User < ActiveRecord::Base devise :omniauthable, :omniauth_providers => [:facebook] def self.from_omniauth(auth) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email user.password = Devise.friendly_token[0,20] end end end
Here we look for a user with that (provider: :facebook, uid: your_uid) pair, and create them if they aren’t in the database. For Facebook users, we create a random password. The expectation is that users logging in with Facebook don’t subsequently want to set a password.
Step 9 – Add a Controller to Handle the Callback
Now add a file:
app/controllers/users/omniauth_callbacks_controller.rb
Create a provider action, this action should have the same name as the provider. In this case, Facebook.
Now we have to write some code to handle the Omniauth callback.
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def facebook @user = User.from_omniauth(request.env["omniauth.auth"]) sign_in_and_redirect @user end end
We have to write a method in our ApplicationController
:
def after_sign_in_path_for(resource) request.env['omniauth.origin'] || root_path end
Your application is now ready.
Run rails s
open up your app and your sign up form should now have a “sign in with facebook” button.
Great, you did it! Now you have an application with email authentication as well as social network sign in.
- Installing phpcs on a Mac ft. VSCode & WordPress, The Really Simple Guide - May 8, 2021
- How To Set Up Your WordPress Development Environment with a Large Database ft. MAMP & Mac, The Really Simple Guide - April 24, 2020
- Next.js ▲ + Typescript + Storybook The Really Simple Guide 2019 - November 25, 2019