-
Notifications
You must be signed in to change notification settings - Fork 15
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
# return to login if canceled
return redirect('/') if input['openid.mode'] == 'cancel'
this_url = URL(Login).to_s
unless input.finish.to_s == '1'
# start doing the auth here
begin
@state.openid_request = Hash.new
oid_request = OpenID::Consumer.new(@state.openid_request, nil).begin(input.identity)
# 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
# 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
# start sreg
sreg = OpenID::SReg::Response.from_success_response(response)
unless sreg.empty?
@state.default_username = sreg['fullname'] || sreg['nickname'] || nil
end
# 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. :)