OAuth Disco – No fluff, just code

OAuth is really nice, but it can be quite confusing to get started with. If you’re the sort of person who likes to look at code instead of pretty graphics then I will show you in about 10 minutes how to get your site connected with Twitter (OAuth v 1.0) and Facebook (OAuth v 2.0).

Preparation

For examples I’ve decided to use two simple Sinatra webapps – easier to see what’s going on by actually clicking through the steps, then trying to explain it all in words.

Before we can get started you need to install a few gems:

sudo gem install sinatra oauth oauth2 json haml

You’ll also need to create a Facebook application and a Twitter application.

Facebook

Let’s get started with Facebook and OAuth v 2.0 since it’s a little bit easier.

Copy and paste the following code to a new file and save it as facebook.rb:

require 'rubygems'
require 'sinatra'
require 'oauth2'
require 'json'
require 'haml'

FACEBOOK_API_KEY = "PASTE_HERE"
FACEBOOK_SECRET_KEY = "PASTE_HERE"

enable :sessions

before do
 @client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET_KEY,
 :site => "https://graph.facebook.com",
 :scheme => :header,
 :http_method => :post,
 )
end

get '/' do
 haml :index, :locals => {
 :url => @client.web_server.authorize_url(:redirect_uri => auth_url)
 }
end

get '/auth' do

 access_token = @client.web_server.get_access_token(
 params[:code], :redirect_uri => auth_url
 )

 session[:profile] = JSON.parse(
 access_token.get('/me?fields=picture')
 )

 redirect '/profile'
end

get '/profile' do

 if session[:profile]
 haml :profile, :locals => {:profile => session[:profile]}
 else
 redirect '/'
 end

end

def auth_url

 uri = URI.parse(request.url)
 uri.path = '/auth'
 uri.query = nil
 uri.to_s

end

__END__

@@ layout
%html
 = yield

@@ index
%form{:action => "#{url}", :method => "post"}
 %input{:type => "submit", :value => "Connect with Facebook"}

@@ profile
%img{ :src => "#{profile["picture"]}", :align => "left"}
%p Welcome #{profile["name"]}!
%p
 You are now connected via Facebook with
 %a{:href => "#{profile["link"]}"} #{profile["name"]}

Then replace FACEBOOK_API_KEY and FACEBOOK_SECRET_KEY with the values given to you by Facebook.

Now you are ready to start the server:

ruby facebook.rb

That’s it, go see it in action at http://perfectline.dev:4567

Twitter

Now let’s do the same procedure with Twitter. It’ pretty similar, except the code and the flow of requests and all those tokens are a bit more complicated.

Start with copy/paste again, this time save the file as twitter.rb:

require 'rubygems'
require 'sinatra'
require 'oauth'
require 'json'
require 'haml'

enable :sessions

TWITTER_CONSUMER_KEY = "PASTE_HERE"
TWITTER_CONSUMER_SECRET = "PASTE_HERE"

before do
 @consumer = OAuth::Consumer.new(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET,
 :site => "https://api.twitter.com",
 :scheme => :header,
 :http_method => :post,
 :request_token_path => "/oauth/request_token",
 :access_token_path => "/oauth/access_token",
 :authorize_path => "/oauth/authorize")
end

get '/' do
 haml :index
end

post '/login' do

 request_token = @consumer.get_request_token :oauth_callback => auth_url

 session[:request_token] = request_token.token
 session[:request_token_secret] = request_token.secret

 redirect request_token.authorize_url

end

get '/auth' do

 request_token = OAuth::RequestToken.new(
 @consumer, session[:request_token], session[:request_token_secret]
 )

 access_token = @consumer.get_access_token(
 request_token, :oauth_verifier => params[:oauth_verifier]
 )

 session[:profile] = JSON.parse(
 access_token.get("/account/verify_credentials.json").body
 )

 redirect "/profile"
end

get '/profile' do

 if session[:profile]
 haml :profile, :locals => {:profile => session[:profile]}
 else
 redirect '/'
 end

end

def auth_url
 uri = URI.parse(request.url)
 uri.path = '/auth'
 uri.query = nil
 uri.to_s
end

__END__

@@ layout
%html
 = yield

@@ index
%form{:action => "/login", :method => "post"}
 %input{:type => "submit", :value => "Connect with Twitter"}
 

@@ profile
%img{ :src => "#{profile["profile_image_url"]}", :align => "left"}
 %p Welcome #{profile["name"]}!
 %p You are now connected via Twitter

Don’t forget to replace TWITTER_CONSUMER_KEY and TWITTER_CONSUMER_SECRET with values given to you by Twitter.

Now let’s continue the disco by fireing up Sinatra again:

ruby twitter.rb

And last point the browser again to http://perfectline.dev:4567.

Afterparty

If some of the code or the flow of requests is a bit confusing then please let me know in the comments, so I can add a more detailed explanation.

Also I would like to know if you prefer this type of hands on approach to more traditional blog posts – that try to explain everything in detail. Please let me know.

And as usual, hope this was useful and helpful to somebody ;)

Tarmo Lehtpuu
Tarmo is the swiss army knife Software Engineer. His deep knowledge on wide range of technologies makes him an efficient problem solver. In addition to Ruby on Rails, he enjoys developing iOS Apps.

2 Comments

  • ketan

    it realy very nice but !!!i wanna some solution for oauth2!!! : )

  • Tarmo Lehtpuu

    Hello Ketan,

    The code in facebook.rb is oauth2 implementation ;)

Liked this post?

There’s more where that came from. Follow us on Facebook, Twitter or subscribe to our RSS feed to get all the latest posts immediately.