Setting up OpenID on Rails

Until last week, GlitterGallery used devise under the hood for it’s traditional authentication system. This week, I replaced that with one based on OpenID. This post covers the strategy I followed. If you’re looking forward to setting up an only-OpenID based authentication solution on your Rails application, I recommend reading this because from my experience, the available documentation is quite old and limited.

remove existing authentication system completely

If your app has no authentication at the moment, you may skip this section. If your application uses devise for authentication, check out this thread to remove devise. I don’t have experience with other auth systems, but my guess would be that removing authlogic and others should be similar.

add the new dependencies

We will work with JanRain’s library for OpenID on ruby applications, and a wrapper to make the process simpler. Add the following to your Gemfile:

gem 'ruby-openid'
gem 'open_id_authentication'

Now run bundle from inside your app directory:

$ bundle install 

add a sessions controller

The idea is that every time a user logs in to our application, we start a new session. To cover that logic, here’s what we’ll begin with:

class SessionsController < ApplicationController
  def new
    # spits out a login form to start session
  end

  def create
    # contains the logic for handling the stuff
    # obtained from the login process
  end

  def destroy
    # contains the logic for destroying the user
    # session (logout)
  end
end

add a sessions resource to routes

We’ll now add a singleton resource to the application routes (config/routes.rb). Notice that we skip the edit functionality because we don’t need it:

resource :session, only: [:new, :create, :destroy]

add a view for the login form for new sessions

Note that I haven’t added any fancy formatting here. OpenID recommends additional formatting guidelines, so you might want to read through this.

<%= form_tag(session_url) do %>
  <%= text_field_tag "openid_identifier" %>
  <%= submit_tag 'Sign in' %>
<% end %>

create a user model

If you already have one, you’ll have to add an accessible attribute field for the identity url:

attr_accessible :identity_url

Also remember to ensure that you have performed a migration to add an identity_url column to the user’s table.

create the login logic

Alright, here comes the fun part. Here’s what I did to create the session once a user has entered his OpenID url on the login.

  
def create
  authenticate_with_open_id do |result, identity_url|
    if result.successful?
      # FIXME - needs normalizing before
      # checking for the identity_url
      unless user = User.find_by_identity_url(identity_url)
        user = User.create(identity_url: identity_url)
      end
      sign_in user
    else
      render 'new'
    end
  end
end

#FIXME – Before you save the identity_url into the User model, it’s good to normalize it, so all identity_url’s are consistent. For example, (http://sarupbanskota.id.fedoraproject.org) and (sarupbanskota.id.fedoraproject.org) shouldn’t be treated as two different urls. I’ll show how, soon.

add helper methods

Now we’ll have to write helper methods to facilitate the sign_in. How you do it depends on your plan, here’s how I did:

module SessionsHelper
  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
    redirect_to dashboard_url
  end
 
  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end
  
  def signed_in?
    !current_user.nil?
  end
  
  def logout
    self.current_user= nil
    delete.cookies[:remember_token]
  end
end

create the signout logic

This is pretty straightforward. If you signed in following my process, then signing out is just a matter of clearing the permanent cookie.

def destroy
  logout
  redirect_to root_url
end
def logout
  self.current_user= nil
  cookies.delete(:remember_token)
end

include the helper in the application controller

Finally, don’t remember to include the helper method in the ApplicationController (app/controllers/application_controller.rb).

include SessionsHelper

With this, you pretty much have a neat OpenID system running. Of course, there’s a lot that can be added to this in the form of SReg extensions, but my goal was to keep the process simple.

Cheers! Remember to share feedback and as if you run into problems!

About these ads

10 thoughts on “Setting up OpenID on Rails

  1. i really wanna know, about:
    -routes
    it just to put
    resource :session, only: [:new, :create, :destroy] on routes
    and where i should put
    attr_accessible :identity_url

    i’m newbie in this stuff
    thanks

  2. Although in the end you can build an object oriented site on top of Word – Press just like you can
    with any other framework. To customize your Word –
    Press blog is not difficult at all and you
    can easily learn how to customize Word – Press yourself and take matters in your own hands.

    Only Word – Press offers you such services where building a software
    is as easy as typing with your keyboard.

  3. Pingback: First iteration outcomes! – some more desi cola

  4. Pretty nice post. I simply stumbled upon your weblog and wished to mention that I have
    really enjoyed browsing your blog posts. In any case I will be subscribing on your
    rss feed and I’m hoping you write once more very soon!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s