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
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.
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
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
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
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
/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
/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:
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'
The code of this Tutorial can be found here.
Salesforce Connected app “Consumer Key” and “Consumer Secret” must be set on
Additional interaction with Restforce can be seen on