Rails: An Omniauth Github Tutorial

I have an exciting new project I just started working on in Rails (more details to come), and my first order of business was implementing Sign in with Github functionality. Luckily, this was really easy to do using the Simple Omniauth Railscast and the omniauth-github gem by Intridea (got to love the Rails community!).

Here’s what to do if you’re looking to incorporate “Sign in with Github” your own website:

sign in with github button

Create an Application on Github

It’s really easy to create your first Github application if you know where to look! Just go to this Register a new OAuth Application page on Github, and register your application!

They accept http://localhost:3000 as your domain, so you can create a test application for testing in your local environment.

The callback url should be something like http://YOUR_DOMAIN/auth/github/callback.

Once you’ve created your application, make sure to save your Github Client Id and Client Secret tokens as Environment Variables in your application.

Install the Gem

The next step is to of course instal the omniauth-github gem. Just add it to your Gemfile:

# Gemfile
source 'https://rubygems.org'

gem 'rails', '4.0.0'

gem "omniauth-github", '1.1.1'

# your other gems

Make sure to run bundle install in your terminal to actually install the gem.

Add Omniauth To Your Initializers

In your config/initializers folder, add an omniauth.rb file:

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user:email,user:follow"
end

Make sure to take a look at these Scopes, and add only the ones you need!

Create a User Model

Create your user model if you haven’t already. To start with, make sure the user has a omniauth provider string (e.g. “github”), a uid string, and a name string. You can analyze the omniauth results later and add any additional information you want to include, such as the user’s email, follower count, image url, etc.

So in your terminal, just run the model generator and then a migration:

$ rails g model user provider:string uid:string name:string
$ rake db:migrate

Create User with Omniauth

In your new User model, add a create_with_omniauth method, which you can modify later if you need extra parameters returned from github via omniauth:

# user.rb
class User < ActiveRecord::Base

  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
    end
  end
end

Create a Sessions Controller

Next run the standard rails generator to create your sessions controller:

$ rails g controller sessions

In your Sessions controller, add a create and destroy actions:

# sessions_controller.rb
class SessionsController < ApplicationController   def create     auth = request.env["omniauth.auth"]     user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)     session[:user_id] = user.id     redirect_to root_url, :notice => "Signed in!"
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url, :notice => "Signed out!"
  end

end

Create a Current User Method

In your Application Controller, add a current_user helper method to use throughout your application:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  helper_method :current_user

  private

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
end

Add the Sign in with Github link

Now, make sure to add the Sign in with Github link or image to where you need it. In my case, I created a users controller, and added a new action, which is where I’m putting my link:

# users_controller.rb
class UsersController < ApplicationController
  def new

  end
end

 

# views/users/new.html.haml
- if current_user
  = "Welcome #{current_user.name}"
- else
  = link_to "Sign in with Github", "/auth/github"

Update Routes

Finally, make sure to update your routes!

Dailycoders::Application.routes.draw do

  root to: "users#new"
  get "/auth/:provider/callback" => "sessions#create"
  get "/signout" => "sessions#destroy", :as => :signout

end

Easy, right?!!! Don’t forget to add tests!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.