Rails and oauth-plugin part 2: the consumer

In the previous post, I showed how you could build a provider with oauth-plugin and Rails. Now, I will demonstrate how to build a consumer (it's a lot easier).

I will assume that your provider is already running on localhost:3000. The consumer will run on localhost:4000 (run it with "rails server -p 4000").

Here we go!

[sourcecode language="bash"]
rails new consumer
cd consumer
[/sourcecode]

Put this in your Gemfile:

[sourcecode language="ruby"]
source 'http://rubygems.org'
gem 'rails', '3.0.7'
gem 'sqlite3'
gem 'devise'
gem "oauth-plugin", ">= 0.4.0.pre1"
[/sourcecode]

And run these commands:

[sourcecode language="bash"]
bundle install
rails generate devise:install
rails generate devise User
rake db:migrate
rails generate controller welcome index
rm public/index.html
[/sourcecode]

And here is your routes.rb:

[sourcecode language="ruby"]
Provider::Application.routes.draw do
devise_for :users
root :to => "welcome#index"
end
[/sourcecode]

Create the consumer

[sourcecode language="bash"]
rails generate oauth_consumer user
rake db:migrate
[/sourcecode]

in app/controllers/oauth_consumers_controller.rb, replace:

[sourcecode language="ruby"]
before_filter :login_required, :only=>:index
[/sourcecode]

by

[sourcecode language="ruby"]
before_filter :authenticate_user!, :only=>:index
[/sourcecode]

Uncomment the methods for devise (go_back, logged_in? currentuser=, deny_access!) in app/controllers/oauth_consumers_controller.rb.

Add to app/models/user.rb:

[sourcecode language="ruby"]
has_one  :test, :class_name=>"TestToken", :dependent=>:destroy
[/sourcecode]

Now go to http://localhost:3000/oauth_clients/ to register your first application with these parameters:

Name:                 Test consumer
Main Application URL: http://localhost:4000/
Callback URL:         http://localhost:4000/oauth_consumers/test/callback

You're redirected to http://localhost:3000/oauth_clients/1. It shows:

Consumer Key:      CRcIJ15MwSqlDTxsH8MpO3En4wjaOxkqeofLioH4

Consumer Secret:   C7uci8xkyMShCf4SNXWPclKbBo3ml1Zf2W2XWu4W

Request Token URL: http://localhost:3000/oauth/request_token

Access Token URL:  http://localhost:3000/oauth/access_token

Authorize URL:     http://localhost:3000/oauth/authorize

Now, you need to put the key and secret in config/initializers/oauth_consumers.rb:

[sourcecode language="ruby"]
OAUTH_CREDENTIALS={
:test =>{
:key => "CRcIJ15MwSqlDTxsH8MpO3En4wjaOxkqeofLioH4",
:secret => "C7uci8xkyMShCf4SNXWPclKbBo3ml1Zf2W2XWu4W",
:expose => true
}
}
[/sourcecode]

Create app/models/test_token.rb. This model will store the token for your provider. If you want to provide helpful methods, take inspiration from lib/oauth/models/consumers/services/.

[sourcecode language="ruby"]
class TestToken < ConsumerToken
TEST_SETTINGS={
:site => "http://localhost:3000",
:request_token_path => "/oauth/request_token",
:access_token_path => "/oauth/access_token",
:authorize_path => "/oauth/authorize"
}

def self.consumer(options={})
@consumer ||= OAuth::Consumer.new(credentials[:key], credentials[:secret], TEST_SETTINGS.merge(options))
end

end
[/sourcecode]

You should now be able to use the URLs "/oauth_consumers/test/client/", "/oauth_consumers/test/callback", "/oauth_consumers/test/callback2"," /oauth_consumers/test/edit",
and "/oauth_consumers/test".

Modify the welcome controller t get the provider data:

[sourcecode language="ruby"]
class WelcomeController < ApplicationController
def index
# cf http://oauth.rubyforge.org/rdoc/classes/OAuth/AccessToken.html
@consumer_tokens=TestToken.all :conditions=>{:user_id=>current_user.id}
@token = @consumer_tokens.first.client
logger.info "private data: "+@token.get("/data/index").body
end

end
[/sourcecode]

To connect a user to an external service link or redirect them to:

/oauth_consumers/[SERVICE_NAME]

Where SERVICE_NAME is the name you set in the OAUTH_CREDENTIALS hash. This will request the request token and redirect the user to the services authorization screen. When the user accepts the get redirected back to:

/oauth_consumers/[SERVICE_NAME]/callback

That's it

This tutorial is really short, and could be explained a bit more, but I'll leave that for another post. You have enough to start tinkering with OAuth. Have fun!