Rails 3 and Devise: authenticating a user while performing a POST action -
using rails 3.0.6, omniauth 0.2.0 , devise 1.2.1, i'm encountering following situation:
i want offer users option authenticate via facebook. have user system set using devise , can auth using facebook. i've spent several hours trying code behavior want 1 specific situation:
- user not logged in
- user has site account
- user authenticates via facebook
i offer user 2 choices @ point
- create account (can dummy account no provided info)
- link facebook authentication existing account
i'm having trouble latter option. user has authenticated still need him log in site account. have action in authenticationscontroller associate authentication logged in user. devise doesn't seem offer way me log user in while staying in same action, though. first attempt this
class authenticationscontroller < applicationcontroller before_filter :authenticate_user!, :only => :auth_link_existing_user ... def auth_link_existing_user ... end however, using method, if user logs in, they're redirected site's root page. know can change devise's sign-in redirect, sign-ins. wanted situation have separate redirect.
after reading through this mailing list question, tried extend sessionscontroller own custom behavior:
def create resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new") set_flash_message(:notice, :signed_in) if is_navigational_format? sign_in(resource_name, resource) if params[:redirect] #new redirect_to params[:redirect].to_sym #new else respond_with resource, :location => redirect_location(resource_name, resource) end end this doesn't work either. i've defined auth_link_existing_user route use post verb (which seems accurate) , redirects can gets.
so have solution in mind: copy , paste code devise's authenticate_user! helper new function can called within controller action without redirecting. seems less ideal me because it's duplication of code , increases coupling--a devise or warden update changes behavior break code well.
has else tried , come more elegant solution? see simpler way me offer or similar behavior users?
update: wants use dirty solution @ end, did:
def auth_link_existing_user # devise/sessions/create resource = warden.authenticate!(:scope => :user, :recall => "registrations#auth_new") set_flash_message(:notice, :signed_in) if is_navigational_format? sign_in(:user, resource) # method defined in ryan bates' railscast omniauth w/devise current_user.apply_omniauth(session[:omniauth]) current_user.save end note action must placed in sessions controller. if not, warden give "invalid email/password" error. incredibly long debugging process find source.
with in place, use login form submit action after user has authenticated.
i how clean solution is, though goes deeper stack.
here how i've implemented similar following devise+omniauth facebook example on devise wiki , modifying facebook method pass on session information login form, this:
if @user.persisted? flash[:notice] = i18n.t "devise.omniauth_callbacks.success", :kind => "facebook" sign_in_and_redirect @user, :event => :authentication else session["devise.facebook_data"] = request.env["omniauth.auth"] redirect_to new_user_session_url end then, in case, i'd check in login controller action session["devise.facebook_data"], submit uid + token form , apply_omniauth if present.
Comments
Post a Comment