The Changelog

Open Source moves fast. Keep up.

oauth2_provider: Make your Rails app an OAuth v2.0 provider

With the likes of Facebook, GitHub, Gowalla, and others adopting OAuth 2.0, client libraries have been popping up everywhere.

If you want to join the cool kids and OAuth2-enable your API, where do you start? ThoughtWorks Studios has released oauth2_provider, a Rails plugin to provide OAuth2 authentication to your app.

Install via RubyGems:

$ gem install oauth2_provider

… and configure via Bundler.

Next, run the supplied generator to create the initializer and migrations:

$ ./script/generate oauth2_provider

Enable OAuth support alongside your regular authentication in your ApplicationController:

class ApplicationController < ActionController::Base

  # the host application's authentication filter
  before_filter :login_required

  # include Oauth2::Provider::ApplicationControllerMethods
  include Oauth2::Provider::ApplicationControllerMethods

  # this checks whether the user is logged in for purposes
  # of an authentication filter. obviously, your host application
  # will have very different code than this.  this example is
  # pulled from the sample host application with which the plugin ships.
  def login_required
    current_user_id = session[:user_id]
    if current_user_id
      User.current = User.new(current_user_id)
    else
      raise "Lack of rights!"
    end
  end

  # required by the OAuth plugin to figure out the currently logged in user
  # must be a string representation of the user.
  # A 'username', 'email' or a db primary key are good candidates.
  protected def current_user_id_for_oauth
    super
  end

  def login_required_with_oauth
    if user_id = self.user_id_for_oauth_access_token
      session[:user_id] = user_id
    elsif looks_like_oauth_request?
      render :text => "Denied!", :status => :unauthorized
    else
      login_required_without_oauth
    end
  end
  alias_method_chain :login_required, :oauth

end

By default, controller actions are not OAuth’d, so you have to opt-in, perhaps with a intermediate controller class:

class ProtectedResourceController < ApplicationController

  # Supported options are:
  #  :only => [:oauth_protected_action...]
  #  :except => [:oauth_unprotected_action...]
  # If no options are specified, defaults to oauth for all actions
  oauth_allowed :only => :index

  def index
    render :text => "current user is #{current_user.email}"
  end

  def no_oauth_here
    render :text => "this content not available via Oauth"
  end

end

[Source on GitHub]


Have comments? Send a tweet to @TheChangelog on Twitter.

Subscribe to The Changelog Weekly – our weekly email covering everything that hits our open source radar.