OpenIdAuthentication With remote_form_for
I finished putting in some sweet AJAXy goodness for comments on the Little Red String site only to find that OpenIdAuthentication was not going to work with remote_form_for. Really, I don’t think that OpenID is going to work with AJAX in general. I peeked inside of the OpenIdAuthentication library and noticed that whenever a user authenticates the redirect_to method is used.
# In module OpenIdAuthentication::begin_open_id_authentication
...
redirect_to(open_id_redirect_url(open_id_request, return_to, method))
...Well redirect_to is not going to work with remote_form_for, but should everyone suffer? Yes.
No. I meant, “no”. RJS has it’s own little redirect_to method and with a classic respond_to block, we can add a little flexibility to the OpenIdAuthentication plugin to make it work if there is an AJAX request.
# Put this in vendor/open_id_authentication_hacks.
# This is compatable with version e6df78367b257886021785ba0260a4b5a4eca793
# of the plugin on 2/21/2008.
module MyOpenIdAuthentication
private
def begin_open_id_authentication(identity_url, options = {})
identity_url = normalize_identifier(identity_url)
return_to = options.delete(:return_to)
method = options.delete(:method)
options[:required] ||= [] # reduces validation later
options[:optional] ||= []
open_id_request = open_id_consumer.begin(identity_url)
add_simple_registration_fields(open_id_request, options)
add_ax_fields(open_id_request, options)
# This is where my hack begins
redirect_url = open_id_redirect_url(open_id_request, return_to, method)
output = ''
respond_to do |format|
format.html {output = redirect_to(redirect_url)}
format.js do
render(:update) { |page| output = page.redirect_to(redirect_url) }
end
end
output
# This is where my hack ends
rescue OpenIdAuthentication::InvalidOpenId => e
yield Result[:invalid], identity_url, nil
rescue OpenID::OpenIDError, Timeout::Error => e
logger.error("[OPENID] #{e}")
yield Result[:missing], identity_url, nil
end
end
ActionController::Base.send :include, MyOpenIdAuthenticationThis works pretty well. However, shouldn’t there be a way to perform the OpenID authentication asynchronously and only call redirect if the user has to actually visit their provider? Let me know in the comments.