Skip to content


Subversion checkout URL

You can clone with
Download ZIP
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, => 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

Something went wrong with that request. Please try again.