Monday, 16 March 2015

Hack With Rack

Hello everyone, Hope you are having a good day.
Ok, some years ago, one of our clients wanted us to implement Social Network (FB,Twitter,Linkedin) sharing functionality. Knowing all the OAuth implementation that one has to deal with, we decided to use this awesome gem called OmniAuth that does all the heavy lifting tasks of OAuth Authorisation with very basic minimum implementation.
So with OmniAuth we manage to get the work done in time but then we wanted OAuth Authorisation to work with Ajax call as well. I remember going all out crazy (Googling + debugging OmniAuth code) to find a way to do it but honestly we couldn’t find any way do it. (Note: This was some years back I’m not sure about the status as of now.)
So we decide to write our own “Rack Middleware” that tampers with the Omniauth Response and treats the ajax request the way we wanted.
The Middleware
class OmniAuthMiddleware
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
request = Rack::Request.new(env)
## Match the request is of type omniauth
if request.xhr? and status == 302 and request.path_info =~ /\/auth\/\w+\z/ and body.class == Rack::BodyProxy
location = headers["Location"]
body = ActionDispatch::Response.new
headers = {'Content-Type'=>'text/javascript; charset=utf-8'}
body.body = ["window.location.href='#{location}'"]
body.headers = headers
status = 200
end
[status,headers,body]
end
end
view raw gistfile1.rb hosted with ❤ by GitHub

and then we insert the Middleware where we wanted it
Rails.application.config.middleware.insert_before OmniAuth::Builder,OmniAuthMiddleware
view raw gistfile1.rb hosted with ❤ by GitHub

Let look at our middleware stack
...
...
...
use Warden::Manager
use Rack::Mongoid::Middleware::IdentityMap
use ExceptionNotifier
use OmniAuthMiddleware ## <--
use OmniAuth::Builder
run MyAppliction::Application.routes
view raw gistfile1.rb hosted with ❤ by GitHub

Yup that's it- a "Hack with Rack" to get a concrete solution for our problem that isn't too fancy but still does the task we needed getting done.

What did I learn today?

Welcome to the what did I learn today series. The intention of this blog spot is to compose the stuff that I learnt day-to-day basics and jo...