Edit I’ve updated some parts to work with the latest version of Rails at the moment (4.1.7). The code of this tutorial is here

The objective

In this post I’m going to explain how to add Salesforce OAuth authentication to a Rails application. Later I’ll be explaining how to use restforce gem to access Salesforce.com data on behalf of the authenticated user.

The Stack


Create a connected APP in salesforce

Head to Setup/Create/Apps:

At the bottom of the screen there’s a section called Connected apps click on New:

Fill the required fields with information about your app, and check “Enable OAuth Settings”:

After the app is created take note of the “Consumer Key” and “Consumer Secret”. The terminology is from OAuth 1.0 those now are called “Client Id” and “Client Secret”.

Ruby on Rails

Open your Gemfile and add the needed gems

  gem 'restforce'
  gem 'omniauth-salesforce'
  gem 'slim-rails'

The gem “slim-rails” is to use slim language for templating. I prefer it over erb because templates look lighter.

Install them running:

  $ bundle install

User model

Generate the user model.

  $ rails g model User provider uid name oauth_token refresh_token instance_url

Modify User model to interact with omniauth

We need to add this to the User model in order to update current user record when the log in is complete. Edit the file located at /app/models/user.rb :

  class User < ActiveRecord::Base
    def self.from_omniauth(auth)
      where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.name = auth.info.name
        user.oauth_token = auth.credentials.token
        user.refresh_token = auth.credentials.refresh_token
        user.instance_url = auth.credentials.instance_url

Add a helper method to interact with current_user

Edit /app/controllers/application_controller.rb, this helper will be available in your app so we can know current user data.

  class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception

    def current_user
      @current_user ||= User.find(session[:user_id]) if session[:user_id]
    helper_method :current_user

Create a Sessions controller

Create a Sessions controller /app/controllers/sessions_controller.rb to manage user sessions.

  class SessionsController < ApplicationController
    def create
      user = User.from_omniauth(env["omniauth.auth"])
      session[:user_id] = user.id
      redirect_to root_url

    def destroy
      session[:user_id] = nil
      redirect_to root_url

Add routes

Modify your /config/routes.rb adding this:

  match 'auth/:provider/callback', to: 'sessions#create', via: [:get, :post]
  match 'auth/failure', to: redirect('/'), via: [:get, :post]
  match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post]

Create a omniauth initializer

Create an initializer /config/initializers/omniauth.rb and add your connected app details.

  OmniAuth.config.logger = Rails.logger

  Rails.application.config.middleware.use OmniAuth::Builder do
    provider :salesforce, 'YOUR-CONSUMER-KEY', 'YOUR-CONSUMER-SECRET'

Add a user widget to all pages

Remove your initial /app/views/layouts/application.html.erb and create an application.html.slim in the same directory with the following content:

      title My Salesforce/Rails connected app
      = stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true
      = javascript_include_tag "application", "data-turbolinks-track" => true
      = csrf_meta_tags
        - if current_user
          p Welcome #{current_user.name}
        - else
          = link_to "Sign in with Salesforce", "/auth/salesforce", id: "sign_in"

      == yield


With the OAuth infraestructure and the current_user helper in place, restforce initialization is quite easy:

 client = Restforce.new :oauth_token => current_user.oauth_token,
      :refresh_token => current_user.refresh_token,
      :instance_url  => current_user.instance_url,
      :client_id     => 'YOUR-CONSUMER-KEY',
      :client_secret => 'YOUR-CONSUMER-SECRET'

Tutorial Code

The code of this Tutorial can be found here. Salesforce Connected app “Consumer Key” and “Consumer Secret” must be set on config/application.rb . Additional interaction with Restforce can be seen on controllers/home_controller.rb.