public
Description: the 4k pocket full-of-gags web microframework
Home | Edit | New

OpenID Authentication

OpenID Authentication
In Camping, sometimes you want to be able to identify people uniquely and safely, but nobody really wants to write yet another registration and login form and email validation routine and password recovery form and buy an SSL certificate so that people don’t transmit their passwords to your app in plaintext. So, lets use OpenID instead! With OpenID all you need is a chunk of code in your camping controller, and a login page. Oh, and you’ll need to gem install ruby-openid. :)

The controller code
class Login < R ‘/openid’
def get
require ‘openid’
require ‘openid/extensions/sreg’
OpenID::Util.logger.sev_threshold = Logger::WARN

  1. return to login if canceled
    return redirect(‘/’) if input[‘openid.mode’] == ‘cancel’
this_url = URL.to_s unless input.finish.to_s == ‘1’
  1. start doing the auth here
    begin
    state.openid_request = Hash.new oid_request = OpenID::Consumer.new(state.openid_request, nil).begin(input.identity)
  2. start sreg
    sreg = OpenID::SReg::Request.new
    sreg.request_fields([‘nickname’, ‘fullname’], false)
    oid_request.add_extension(sreg)
    oid_request.return_to_args[‘finish’] = ‘1’
    redirect(oid_request.redirect_url(URL.to_s, this_url))
    rescue OpenID::DiscoveryFailure
    ‘Couldn\’t find an OpenID at that address, are you sure it is one?’
    end
    else
  3. finish the auth here
    response = OpenID::Consumer.new(@state.openid_request || {}, nil).complete(input, this_url)
    @state.delete(‘openid_request’)
    case response.status
    when OpenID::Consumer::SUCCESS
    @state.identity = response.identity_url.to_s
  4. start sreg
    sreg = OpenID::SReg::Response.from_success_response(response)
    unless sreg.empty?
    @state.default_username = sreg[‘fullname’] || sreg[‘nickname’] || nil
    end
  5. end sreg
    grab_avatar
    when_done = @cookies.once_logged_in
    @cookies.delete(‘once_logged_in’)
    redirect(when_done || Home)
    when OpenID::Consumer::FAILURE
    ‘The OpenID thing doesn\’t think you really are that person, they said: ’ + response.message
    else
    ’Crazy response is crazy: ’ + response.inspect
    end
    end
    end
    def post; get; end
    end
    This assumes you have a controller named Home where you want to send users once logged in. You can that to whatever of course. You can also have it load other SReg (Simple Registration) fields by adding them to the list in the first half of this code. This gives the user an opportunity in most cases to send you that information by simply clicking a button or checking a box, though be aware they are also able to login without sending this information, and that some OpenID providers do not support it at all.

Now in your other controllers, you can simply add code along the lines of return redirect(LoginPage) unless @state.identity, or you can build more complex helper’s which set the once logged in cookie and display the login page. :)

Last edited by whymirror, Thu Aug 20 15:14:52 -0700 2009
Home | Edit | New
Versions: