Ruby on Rails 4, Salesforce OAuth authentication and Restforce
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.
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 Stack
Salesforce
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
user.save!
end
end
end
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
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
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
end
def destroy
session[:user_id] = nil
redirect_to root_url
end
end
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'
end
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:
html
head
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
body
div#current_user_status
- if current_user
p Welcome #{current_user.name}
- else
= link_to "Sign in with Salesforce", "/auth/salesforce", id: "sign_in"
== yield
Restforce
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
.
Comments