-
Notifications
You must be signed in to change notification settings - Fork 37
Using omniauth
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.
First, create a brand new app :
ramaze create omnitest
cd omnitest
Change the 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
.
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
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
At this stage, it should already be working, and we can try it out. Start the server :
bundle exec thin -p 4567 --rackup config.ru start
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
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 ?>
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
We also have to tell our app to load thse models, so change app.rb
to :
require 'rubygems'
require 'ramaze'
# Make sure that Ramaze knows where you are
Ramaze.options.roots = [__DIR__]
require __DIR__('controller/init')
require __DIR__('model/init')
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 using Github with Ramaze
- Website
- Google Groups
- User Guide
- [#ramaze on the Freenode network] (http://webchat.freenode.net/?channels=ramaze)