Switch branches/tags
Nothing to show
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

  • mkdir oauth
  • cd oauth
  • rails new provider
  • cd provider
  • 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 Data index
rails g oath_provider
rm public/index.html

Add this into your User model

references_many :client_applications
references_many :tokens, :class_name => "OauthToken", :order => "authorized_at desc"

Add this into your oauth_clients_controller.rb:

alias :login_required :authenticate_user!

In oauth_clients_controller.rb, find and replace the line reads @tokens = current_user.tokens.find(:all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null')


@tokens = current_user.tokens.includes(:client_application).where('oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null')

In config/application.rb, add this code:

require 'oauth/rack/oauth_filter'
config.middleware.use OAuth::Rack::OAuthFilter

In app/controllers/oauth_controller.rb, add this code:

alias :logged_in? :user_signed_in?
alias :login_required :authenticate_user!

Modify the Data#index to add some data:

class DataController < ApplicationController
  before_filter :oauth_required

  def index
    @data = { "coincoin" => "o< o<" }

    respond_to do |format|
      format.json { render :json => @data }

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

5. Explain :include issue

As mentioned in oauth-plugin guide we should use has_many :tokens, :class_name => "OauthToken", :order => "authorized_at desc", :include => [:client_application] with the :include option.

Actually :include is for ActiveRecord eager-loading feature and it doesn't work with Mongoid, so I thought I should find an equivalent of it in Mongoid.

After doing a research I found that Mongoid originally didn't support eager-loading, then started supporting eager-loading from version 2.2.0

We can use this feature by using Model#includes method as guided here

So I think we should remove the :include => [:client_application] option in User model, then add .includes(:client_application) to the controller as above.

6. Issues with oauth-plugin + mongoid

You will encounter these one when you trying to connect consumer with provider on step 5 in consumer guide.

  • Dynamic finders don't seem to work. You'll get the exception with 'find_by_key', we need to modify the oauth-plugin gem directly (as the author hasn't provide a fix yet).

Do this commands:

bundle show oauth-plugin # to know where it was installed.
cd /path/to/oauth-plugin/installed
cd lib
grep -rn 'find_by_' .

Let's change all the .find_by_<a_key>(<a_value>) with .where(:<a_key> => <a_value>).first E.g:

# this one
@token = ::RequestToken.find_by_token! params[:oauth_token]

# should be changed to
@token = ::RequestToken.where(:token => params[:oauth_token]).first
  • undefined method 'expand_complex_criteria' for #<Array:0x00000102934308>

In lib/oauth/rack/oauth_filter.rb of oauth-plugin gem, find the line (around line #27) which reads: if token = Oauth2Token.first(:conditions => ['invalidated_at IS NULL AND authorized_at IS NOT NULL and token = ?', token_string])

change it to if token = Oauth2Token.where(:invalidated_at => nil, :authorized_at.ne => nil, :token => token_string).first

Then find the line (around #45) which reads: oauth_token = client_application.tokens.first(:conditions => { :token => request_proxy.token })

change it to oauth_token = client_application.tokens.where(:token => request_proxy.token).first