Last active
January 1, 2016 15:49
-
-
Save jarrad/8167062 to your computer and use it in GitHub Desktop.
Needed to extend Devise to integrate and authenticate with a legacy app. Stitched this solution together after reading multiple articles and trying various combinations therein.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/devise.rb | |
require 'devise/models/remote_authenticatable' | |
require 'remote_auth_strategy' | |
Devise.setup do |config| | |
# all the other shenanigans... | |
config.warden do |manager| | |
manager.intercept_401 = false | |
manager.default_strategies(:scope => :user).unshift :remote | |
end | |
# and any more shenanigans... | |
end | |
# inform Warden about our custom auth strategy | |
Warden::Strategies.add(:remote, RemoteAuthStrategy) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/remote_auth_strategy.rb | |
class RemoteAuthStrategy < Warden::Strategies::Base | |
def valid? | |
Rails.logger.info '[INFO] remote strategy valid?' | |
params['user'] && (params['user'].fetch('email') || params['user'].fetch('password')) | |
end | |
def authenticate! | |
Rails.logger.info '[INFO] remote strategy authenticate' | |
# assuming we submitted from a devise form... | |
user = params[:user] | |
u = User.new | |
# use our custom model to authentication the given credentials | |
u = u.remote_authentication( :email => user[:email], :password => user[:password] ) | |
u.nil? or u.eql? false ? fail!('unauthorized') : success!(u) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/devise/models/remote_authenticatable.rb | |
module Devise | |
module Models | |
module RemoteAuthenticatable | |
extend ActiveSupport::Concern | |
# | |
# Here you do the request to the external app using an | |
# ActiveResource model | |
#. | |
# If the authentication is successful, you should return | |
# a resource instance. | |
# | |
# If the authentication fails, you should return false. | |
# | |
def remote_authentication(authentication_hash) | |
begin | |
# invoke /users/sign_in on other app | |
# ensure you use SSL :-) | |
response = MyRemoteService::User.get(:sign_in, {:email => authentication_hash[:email], :password => authentication_hash[:password]}) | |
rescue | |
return false | |
end | |
return false if response.nil? | |
# create our local (PORO) User model to hold the details | |
user = User.new | |
user.id = response['id'] | |
user.email = response['email'] | |
user | |
end | |
module ClassMethods | |
#################################### | |
# Overriden methods from Devise::Models::Authenticatable | |
#################################### | |
# | |
# This method is called from: | |
# Warden::SessionSerializer in devise | |
# | |
# It takes as many params as elements had the array | |
# returned in serialize_into_session | |
# | |
# Recreates a resource from session data | |
# | |
def serialize_from_session(id,email) | |
resource = self.new | |
resource.id = 1 | |
resource.email = email | |
resource | |
end | |
# | |
# Here you have to return and array with the data of your resource | |
# that you want to serialize into the session | |
# | |
# You might want to include some authentication data | |
# | |
def serialize_into_session(record) | |
[record.id, record.email] | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
# PORO User object... | |
class User | |
include ActiveModel::Validations #required because some before_validations are defined in devise | |
extend ActiveModel::Callbacks #required to define callbacks | |
extend Devise::Models | |
attr_accessor :email, :password, :id | |
define_model_callbacks :validation #required by Devise | |
# because we include our custom model in the devise/models directory, | |
# devise will use it with no further action required | |
devise :remote_authenticatable | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment