Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Using 'oauth-plugin' and 'mongodb'.

Steps from scratch

1. Create new project

  • cd oauth
  • rails new consumer
  • cd consumer
  • add these gems to your Gemfile
gem 'rails', '3.0.12'

gem 'devise'
gem 'oauth-plugin', '~> 0.4.0'

gem 'mongoid'
gem 'bson_ext'
  • bundle install

Now you have:

  • an authentication system installed (Devise)
  • oauth-plugin which helps you a lot in generating files for Oauth
  • mongoid a driver for mongodb
  • bson_ext which mainly for mongo peformance improvement

2. Config the app to use mongodb

  • delete config/database.yml
  • rails g mongoid:config
  • replace require 'rails/all' in config/application.rb with
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
# require "sprockets/railtie" # Uncomment this line for Rails 3.1+

3. Config the generators

This step is important, you need to do this before generating/installing Devise model, Oauth things...

Add this code into your application.rb, uncomment haml/rspec if you use them. Keep the mongoid option as that is what we want.

config.generators do |g|
  g.orm             :mongoid
  #g.template_engine :haml
  #g.test_framework  :rspec

From now on, the generators know they should invoke mongoid instead of activerecord when generating things...

4. Generates things

rails g devise:install
rails g devise User
rails g controller Welcome index
rails g oath_consumer User
rm public/index.html

Add this to your User model:

references_many :consumer_tokens
index "consumer_tokens.token"

In app/model/consumer_token.rb, find the line reads embedded_in :user, :inverse_of => :consumer_tokens

change it to

referenced_in :user, :inverse_of => :consumer_tokens

Add this to oauth_consumers_controller.rb, comment out the line reads before_filter :login_required, :only=>:index. Uncomment/add new line that reads before_filter :authenticate_user!, :only=>:index

In oauth_consumers_controller.rb, make sure these methods are NOT commented out: go_back, logged_in?, current_user=, deny_access!

Added this to User model: references_one :test, :class_name => "TestToken", :dependent => :destroy (TestToken is the model for the provider, we would have TwitterToken, FacebookToken...etc)

Create a model file named test_token.rb in app/models/ with the content:

class TestToken < ConsumerToken
    :site => 'http://localhost:3000', # this is the URL to `provider` app
    :request_token_path => '/oauth/request_token',
    :access_token_path => '/oauth/access_token',
    :authorize_path => '/oauth/authorize'

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

In config/routes.rb, add your root path root :to => "welcome#index"

5. Connect with the Provider

Let's start provider app on port 3000 and consumer app running on port 4000 (rails s -p 4000)

Navigate to http://localhost:3000/users/sign_up to register an account.

Navigate to http://localhost:3000/oauth_clients/ to register your app with these info:

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

You will be redirected to oauth_client show page with credentials (yours will be different)

OAuth details for Test Consumer

Consumer Key: d8KBiaD98Mnp2vyB9A8ZSAT0vpKu5kdFtAXUsZup

Consumer Secret: UDdD5HAefrRZ1afguDy0WrTALYwZ8KXWKgLiSJCE

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

In config/initializers/oauth_consumers.rb, add the credentials above. The content will look like:

  :test => {
    :key => 'd8KBiaD98Mnp2vyB9A8ZSAT0vpKu5kdFtAXUsZup',
    :secret => 'UDdD5HAefrRZ1afguDy0WrTALYwZ8KXWKgLiSJCE',
    :expose => true

Restart your consumer app if it was running when you changed the content of this initializer.

Modify the content of Welcome#index to get the provider data:

class WelcomeController < ApplicationController
  def index
    @consumer_tokens = TestToken.where(:user_id =>
    @token = @consumer_tokens.first.client 'private data' + @token.get('/data/index').body

Go to http://localhost:4000/oauth_consumers to see all the services. Actually we have only 1 here, it's the 'test' service which owned by 'TestToken' model.

Click on the service (here is test) then give it access

Go to http://localhost:4000 and you will see the data from provider in log