Skip to content
leucos edited this page Sep 18, 2012 · 6 revisions

Using Omniauth is simple. Omniauth makes it easy because it's not Rails centric.

Based on the examples seeen on it's home page, it is quite easy to convert it to Ramaze.

This page will walk you through creating an application, enabling github authentication, and hooking this authentication with the Ramaze User helper.

Creating the app

First, create a brand new app :

ramaze create omnitest
cd omnitest

Add a Gemfile to handle your gem dependencies :

source 'https://rubygems.org'

gem 'ramaze'
gem 'omniauth'
gem 'sequel'
gem 'sqlite3'

gem 'thin'

gem 'omniauth-github'

and install them with bundle.

Load the required authentication stategies

You need to create an application under your GitHub account (https://github.com/settings/applications, then Register new application). As callback URL, you need to provide the URL that GitHub will send back to your browser. For instance, if you're testing on localhost, port 4567, just write http://127.0.0.1:4567/auth/github/callback

The /auth/github/callback part is standard for Omniauth, you shouldn't change this.

Then change the values for KEY and SECRET in the config.ru below.

Omniauth is Rack-based, so the necessary middlewares have to be loaded. Change your config.ru to this :

require 'omniauth'                                                                                                                                                                        
require 'omniauth-github'
 
require ::File.expand_path('../app', __FILE__)
 
use Rack::Session::Cookie
use OmniAuth::Builder do
  provider :github, "KEY", "SECRET"
end
 
Ramaze.start(:root => Ramaze.options.roots, :started => true)

run Ramaze

Creating the callback controller and method

Let's create now a Github controller, that will handle GitHub response (happy, or unhappy).

Let's call it controller/github.rb, and fill it with this :

class Github < Ramaze::Controller
  map "/auth/github/"
 
  def callback
    auth = request.env['omniauth.auth']
    Ramaze::Log.info auth.inspect
                                                                                                                                                                                              
    session[:github] = auth
    redirect MainController.r(:index)
  end 
 
end

Don't forget to load this controller in controller/init.rb

Trying things out

At this stage, it should already be working, and we can try it out. Start the server :

bundle exec ramaze start -s thin -p 4567

And then head to : http://127.0.0.1:4567/auth/github

If you try for the first time, it should redirect you to GitHub. If you click "Allow", you will be sent back to /auth/github/callback with some arguments, and then redirected by your callback to /index

Gathering some information

As you might have noticed, you get a bunch of information in the callback. It's being logged with Ramaze::Log.info auth.inspect. Let's use this and display your name and avatat on the index page if you're logged in.

Since we're recording all the GitHub returned data in the user's session (session[:github] = auth ), it's quite easy to do. Just change your index view, and add these lines at the top :

<?r if session[:github] ?>
<img src="#{session[:github][:info][:image] ? session[:github][:info][:image] : "http://placekitten.com/80/80"}" alt="">
  <p>Hello #{session[:github][:info][:nickname]} (#{session[:github][:info][:name]})</p>
<?r end ?>

Hanging out with the UserHelper

Ok, this is ÜberCool, but it could be even better if we could hook UserHelper authentication with this, so we can still use our friend UserHelper in our apps.

This can be done. But it needs a little more work, since we have to create a User model.

We first need a proper model/init.rb, like this one :

require 'sequel'

Sequel::Model.plugin(:schema)
DB=Sequel.sqlite('./app.db')

require __DIR__('user')

Then of course, our User model in model/user.rb :

class User < Sequel::Model
                      
  set_schema do       
    primary_key :id 
    varchar :github_uid
    numeric :visits                                                                           
  end                 
                      
  create_table if !table_exists?
                      
end

Now, we want our small app to have the following behaviour : when someone comes and authenticates with GH, we create a new User in our database if we haven't seen him, otherwise we just add a new visit to this user's visit counter.

Let's change our model, and an authentication callback.

def self.authenticate(creds)
  # We need the uid returned by GH and the session
  uid, session = *creds
 
  # Let's see if this guy has been here within the current session
  return User[:github_uid => uid] if session[:github] and session[:github][:uid] == uid 
                                                                                                                                              
  Ramaze::Log.info("user_callback called with cred #{uid}")

  # Get user from github UID
  # Create one if none exist
  usr = User[:github_uid => uid] || User.create(:github_uid => uid, :visits => 0)
 
  # Add one to visit counter
  usr.visits +=1·
  Ramaze::Log.info("user #{usr.github_uid} has #{usr.visits}")
 
  # Save our friend, and return usr (positive side effect !)
  usr.save 
end 

Ok, good. Now we can "log in" a user in our app if he's logged with Gihub. But we have to trigger this login from the github callback :

class Github < Ramaze::Controller
  map "/auth/github/"
  helper :user

  def callback
    auth = request.env['omniauth.auth']
    Ramaze::Log.info auth.inspect

    # Log in user
    user_login([auth[:uid], session])

    session[:github] = auth
    redirect MainController.r(:index)
  end

end

We're done : when a user sucessfully auths himself on GitHub, our callback is triggered and user_login is called, and user_login calls out User#authenticate method from model in the backstage.

You can checkout this example from

Clone this wiki locally