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!

rails new consumer
cd consumer

Put this in your Gemfile:

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

And run these commands:

bundle install
rails generate devise:install
rails generate devise User
rake db:migrate
rails generate controller welcome index
rm public/index.html

And here is your routes.rb:

Provider::Application.routes.draw do
devise_for :users
root :to => "welcome#index"
end

Create the consumer

rails generate oauth_consumer user
rake db:migrate

in app/controllers/oauth_consumers_controller.rb, replace:

before_filter :login_required, :only=>:index

by

before_filter :authenticate_user!, :only=>:index

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:

 has_one  :test, :class_name=>"TestToken", :dependent=>:destroy

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:

 OAUTH_CREDENTIALS={
:test =>{
:key => "CRcIJ15MwSqlDTxsH8MpO3En4wjaOxkqeofLioH4",
     :secret => "C7uci8xkyMShCf4SNXWPclKbBo3ml1Zf2W2XWu4W",
     :expose => true
   }
 }

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/.

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

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:

 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

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!

About these ads

22 thoughts on “Rails and oauth-plugin part 2: the consumer

  1. Great post!
    but I had some trouble here..
    when the consumer authorize the test app.. and get redirected to the callback url.. the user / current_user ? is null.. so the consumer_token.user_id is null too..
    I can’t figured out the problem.. please help :(

  2. Hi Géal,

    First of all, awesome two part post. This has been the most useful, and step by step Oauth tutorial I’ve found yet.

    I am going through everything step by step, but I keep getting stuck trying to connect the consumer to the provider.

    My steps:
    1. Create provider/consumer as directed
    2. Create a user account on provider, log in, and create a client
    3. Add generated credentials to consumer
    3. Create another user account on consumer, log in, and try to connect to the provider

    As the consumer redirects to the provider to get authorization, i get the following error on the provider

    – ArgumentError (wrong number of arguments (0 for 2))

    But I can’t figure out where?

    I have included the full error below.

    Is there something obvious that you can help me see? If not, no worries, still a big thanks for the effort you put in write to the posts!

    =======================================================================

    Started GET “/oauth/authorize?oauth_token=LLPX0BFno7FhzBaDiJcSKTKr7thuobM1gjI78zU3″ for 127.0.0.1 at 2011-10-25 23:41:18 -0700
    ←[1m←[35mOauth2Token Load (0.0ms)←[0m SELECT “oauth_tokens”.* FROM “oauth_tokens” WHERE “oauth_tokens”.”type” = ‘Oauth2Token’ AND (invalidat
    ed_at IS NULL AND authorized_at IS NOT NULL and token = ‘LLPX0BFno7FhzBaDiJcSKTKr7thuobM1gjI78zU3′) LIMIT 1
    Processing by OauthController#authorize as HTML
    Parameters: {“oauth_token”=>”LLPX0BFno7FhzBaDiJcSKTKr7thuobM1gjI78zU3″}
    Completed in 1ms

    ArgumentError (wrong number of arguments (0 for 2)):

    Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.7/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
    Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.7/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (2.0ms
    )
    Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.0.7/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/l
    ayout (13.0ms)

  3. I’m having a problem using the client endpoint for an oauth service when the format is specified.

    I try to specify the return format using the following url:
    http://consumer.dev/oauth_consumers/dupl/client/series.json

    But Rails just json formats the returned *html* response, and doesn’t send the format as part of the endpoint.

    from the consumer log:

    Started GET “/oauth_consumers/dupl/client/series.json” for 127.0.0.1 at 2011-12-14 15:06:22 -0500
    Processing by OauthConsumersController#client as JSON
    Parameters: {“id”=>”dupl”, “endpoint”=>”series”}

    and the client log:

    Started GET “/series/” for 127.0.0.1 at 2011-12-14 15:06:22 -0500

    am i missing something?

    • I don’t really get what you’re trying to do. Could you elaborate a bit? (like, who is the provider, who is the consumer, where is the data, and where do you make the call?)

  4. Is there a zipped version of the rails app available? Would like to see it all in context and try out… If yes & you can provide this, can it run on the latest version of rails? (v3.2.1)

  5. Pardon me if the question is too naive.
    I followed the tutorial completely till ” creating the app/models/test_token.rb” part. After that I was lost. We never wrote any migration for this model, yet we try to do @consumer_tokens=TestToken.all :conditions=>{:user_id=>current_user.id} in the welcome controller.
    I tried doing
    c = TestToken.new.client
    c.get(“/services/blocked_ips.json”).body
    but it gives me “Invalid OAuth Request”. can’t figure out what exactly i missed. Any help is appreciated.

    • I, too have been struck by this error. I’ve been wrestling with these tutorials all weekend, I’ve decided to give up and ask for help.

      In addition to this error:
      NoMethodError in WelcomeController#index

      undefined method `client’ for nil:NilClass

      I’m also getting a 500 Server Error when I try to access http://localhost:4000/oauth_consumers/test

      Also, this:
      NameError in OauthConsumersController#show

      uninitialized constant Oauth::Controllers::ConsumerController::Oauth2Token

      Rails 3.2.5

      Any thoughts?

      • For now, I don’t know where your problems might come from. These tutorials are one year old, so I will go again through the whole process, and see if some bugs were introduced in the meantime.

      • I’m getting the same error, I’ve tried this both on Rails 3.2.3 and Rails 3.2.8. The “client” and “get” methods in app/controllers/welcome_controller.rb are returning “undefined methods” errors.

  6. Rails + oauth-plugin + mongodb part 1: Provider | Ruby on Rails freelancer

  7. Very nice and easy to follow and managed to make it work using Rails 3.2.11 with ruby 1.9.3.
    Needed some changes to the oauth producer odels, because they were not exposing the list of attributes that could be mass assigned, just adding attr_accessible with the list of attributes causing the errors on the producer soved it.
    Did not need to change anything important on the consumer side.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s