Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warden authenticate recall not getting called

I'm trying to have ajax login using devise, but I can't seem to get this working. The problem is that I have confirmable strategy enabled on devise, warden.authenticate! should fail on inactive users and render the failure action, instead it renders the default action. I notice that many tutorials have the same set ups. I am using rails 4.0.0 and devise 3.2.2.

class SessionsController < Devise::SessionsController
   def create
     #problem: failure not getting called
     resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#failure") 
     sign_in(resource_name, resource)
     render json: {success: true}
   end 

  def failure
     render json: {success: false, errors: ["Login failed!"]}
  end
end

The devise.rb is set up as follow,

config.http_authenticatable_on_xhr = false
config.navigational_formats = ['*/*', :'*/*', :html, :json]

The routes.rb has the following,

devise_for :users, controllers: {registrations: "registrations", sessions: "sessions"}

The signin form,

 <%= form_for(resource, as: resource_name, 
    url: session_path(resource_name), 
    format: :json,
    html:{id:"signin_form"},
    remote: true) do |f| %>
<%= f.label(:email, "Email") %> 
<%= f.text_field(:email, class: "field text") %> 
<%= f.label(:password, "Password") %> 
<%= f.text_field(:password, class: "field text", id: "user_signin_password") %>  

<%= f.submit "Sign in", class: "theme_color btn key" %>
<% end %>

Since the failure action is not getting called, the default new action is rendered with response header as follow,

Content-Type   text/html; charset=utf-8
Location       http://localhost:3000/users/sign_in.js

I am also curious why it renders .js instead of .json.

Can someone point me out what I missed? Thanks

like image 550
jctank Avatar asked Dec 05 '13 03:12

jctank


1 Answers

After spending hours debugging the app, I found there's a bug inside devise's activatable.rb file. As I follow along with the options and found that the devise's registered hook after_set_user does not throw with the recall option.

This seems only happen to inactive accounts(have confirmable strategy enabled, but account has not yet confirmed) trying to login with an existed email/username. However, if trying to login with a nonexisten email/username, the above does works as authenticate! throws :warden with the recall option.

I'm glad there's someone also found the same bug and provided the patch, but am curious why they don't merge with it. solution can be found here!

like image 170
jctank Avatar answered Sep 28 '22 04:09

jctank