We wanted to make signing up with skroutz a single click away by enabling the usual social authentication methods like google, facebook or twitter.
After a few iterations we realized that the scheme we were using until then was getting way out of control, what we needed was a clean abstraction for authentication mechanisms.
There are plenty of rails authentications plugins out there, but they are either very opinionated about your user model or involve writing a big pile of configurations.
So before starting to write our own backend we saw warden, one of the best rack middlewares ever.
- It was rack based, so we could hook it with our sinatra apps and monitoring tools.
- It was dead easy to define more auth strategies.
- It had a clean api.
- It seemed well documented & supported.
- It had great code.
The first step was to migrate our simple username/password login to warden and to tie it with our app logic (session handing etc). After a small refactoring the code was ready and deployed.
Fun with strategies
Now that everything was setup, we simply had to write small encapsulated auth strategies like google, facebook and twitter. (more on that later)
But it wasn't funny all the time...
- Yahoo was too standard compliant so george had to patch
ruby-openidto make it work and he is a changed man after that.
- When I started writing the facebook strategy i was prepared for endless debugging nights but after all facebook graph api is great!
Here are our warden setup, make sure to install
rails_warden, a really thin wrapper around warden that will make your life easy.
Some small notes on how things work, lets take facebook for example, The login page POSTs a simple parameter like
/login, the facebook strategy drops in and redirects the user to facebook, after authenticating our callback does the user login.
The question is why we don't make the facebook button redirect the user directly to facebook instead of doing a stupid POST request? The reason is that this way all the auth logic is enclosed in the strategy, you don't have to construct facebook redirects in the template.