Devise for pure ajax, no redirect. Possible?

2,852 views
Skip to first unread message

Larryachu

unread,
Mar 3, 2011, 6:54:52 AM3/3/11
to Devise
Hi,

I have been following the instructions on this board and OS board on
configuring Devise to work with AJAX. It has been a difficult
journey, but I think I am close. For anyone who is trying this, here
is a short summary of steps I took (after Devise is working in normal
http mode)

S1. Make a custom sessions controller (https://gist.github.com/418243)
and put it in app/controllers/users/sessions_controller.rb (my model
happens to be users, yours can be different)

S2. Edit config/initializers/devise.rb to contain the following lines:
config.http_authenticatable = false
config.http_authenticatable_on_xhr = false
config.navigational_formats = [:"*/*",:html] #
tried :js, :JS, :json, no effect

S3. Edit config/routes.rb to contain the route below:
devise_for :users, :controllers => { :sessions => "users/sessions" }

S4. In html.erb, use POST to create session:
var url = '/users/sign_in.js'
$.ajax({ type: 'POST', url: url,
data: { "remote" : true, "commit" : "Sign in", "utf8" : "✓", "user" :
{
"remember_me" : v_login_remember,
"password" : v_login_password,
"email" : v_login_email},},
success: function(json){ // do something here}
});


My observations are:
O1. resource = warden.authenticate!(:scope => resource_name, :recall
=> "failure") does not call "failure", as others have pointed out ()

O2. warden.authenticate! redirects after successful sign_in (if this
is true, could someone show me how to disable this redirect? If this
is not true, could someone point out where the redirect is taking
place?) Redirect happens even if sign_in_and_redirect function is
removed from https://gist.github.com/418243

O3. Actually, if ajax is the goal, instead of https://gist.github.com/418243,
all you need in the sessions controller is 4 lines.

class Users::SessionsController <
Devise::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name)
render :json => { :success => true }
end
end

O4. I still get redirects after successful sign_in, unsuccessful
sign_in, and sign_out (destroy)

O5. https://gist.github.com/589639 describes a fix for login redirect,
but Im lost on where to put this file. Has anyone tried this? Love
to hear some details.

O6. If anyone has any insights on how to disable redirects in Devise,
I would love to hear more. It really defeats the point of using ajax
if my page is going to reload after any authentication action.

O7. For dealing with browser http authentication pop-up, this link has
good resources:
http://groups.google.com/group/plataformatec-devise/browse_thread/thread/30553801dc60076a/ae27657844d6e505?lnk=raot

The question is: How do I disable any devise/warden redirect after
login logout signup, actions, so that I can have only ajax do the
work.

Rails 3.0.3, devise 1.1.5 master branch, warden 1.0.3/1.0.2

Larryachu

unread,
Mar 3, 2011, 9:59:43 PM3/3/11
to Devise
I found the problem, and it is embarrassing, but this issue is solved
for me. My observation that warden was redirecting was entirely
incorrect. The 'redirect' I was seeing was due to type="submit" in
the input fields I was using. I had:

<input id="login_submit" type="submit" value="Sign in" />

in my html, which I used jQuery to monitor the click event. The
submit action was causing my page to reload. Simply go to
type="button" solved my problem.

<input id="login_submit" type="button" value="Sign in" />

There it is. This solves my problem with redirect, as it turns out,
had nothing to do with Devise or warden. Hope someone out there finds
this useful!

Larry
> removed fromhttps://gist.github.com/418243
>
> O3. Actually, if ajax is the goal, instead ofhttps://gist.github.com/418243,
> all you need in the sessions controller is 4 lines.
>
> class Users::SessionsController <
> Devise::SessionsController
>   def create
>     resource = warden.authenticate!(:scope => resource_name)
>     render :json => { :success => true }
>   end
> end
>
> O4. I still get redirects after successful sign_in, unsuccessful
> sign_in, and sign_out (destroy)
>
> O5.https://gist.github.com/589639describes a fix for login redirect,
> but Im lost on where to put this file.  Has anyone tried this?  Love
> to hear some details.
>
> O6. If anyone has any insights on how to disable redirects in Devise,
> I would love to hear more.  It really defeats the point of using ajax
> if my page is going to reload after any authentication action.
>
> O7. For dealing with browser http authentication pop-up, this link has
> good resources:http://groups.google.com/group/plataformatec-devise/browse_thread/thr...

MissingHandle

unread,
Mar 3, 2011, 10:42:41 PM3/3/11
to Devise
Thanks for the post. Although I'm not (yet) ajaxifying sign_in, I'm
sure this will come in useful in the future. maybe turn it into a
wiki post?
> > O5.https://gist.github.com/589639describesa fix for login redirect,

Walter Lee Davis

unread,
Mar 4, 2011, 11:02:59 AM3/4/11
to plataforma...@googlegroups.com

On Mar 3, 2011, at 9:59 PM, Larryachu wrote:

> I found the problem, and it is embarrassing, but this issue is solved
> for me. My observation that warden was redirecting was entirely
> incorrect. The 'redirect' I was seeing was due to type="submit" in
> the input fields I was using. I had:
>
> <input id="login_submit" type="submit" value="Sign in" />
>
> in my html, which I used jQuery to monitor the click event. The
> submit action was causing my page to reload. Simply go to
> type="button" solved my problem.

In Prototype, there is the useful Event.stop() function which lets you
keep the Submit button (for usability reasons) and still have it
behave the way you want it to. If you build your form to work with and
without Ajax, you can get everything you want for free like this:

$('yourForm').observe('submit', function(evt){
evt.stop(); //cancel the default behavior
this.request({ //ajaxify the form, based on its attributes
onSuccess: function(transport){
//do cool stuff
},
onFailure: function(transport){
//sad face
}
});
});

I'd be very surprised if there wasn't something similar in jQuery.

Walter

tron

unread,
Mar 4, 2011, 4:18:12 PM3/4/11
to Devise
nice efforts, thanks a lot

as for O3: you dont need the authenticate! call, can bypass the
warden -> failure_app dance
by simply calling warden.authenticate (without bang)
then test nil to fallback to failure behaviour

class Users::SessionsController <
Devise::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name)
render :json => { :success => true }
end
end

as for S2
config.navigational_formats = [:"*/*",:html] #
tried :js, :JS, :json, no effect

please someone comment on why :"*/*"???

thanks
V
> removed fromhttps://gist.github.com/418243
>
> O3. Actually, if ajax is the goal, instead ofhttps://gist.github.com/418243,
> all you need in the sessions controller is 4 lines.
>
> class Users::SessionsController <
> Devise::SessionsController
>   def create
>     resource = warden.authenticate!(:scope => resource_name)
>     render :json => { :success => true }
>   end
> end
>
> O4. I still get redirects after successful sign_in, unsuccessful
> sign_in, and sign_out (destroy)
>
> O5.https://gist.github.com/589639describes a fix for login redirect,
> but Im lost on where to put this file.  Has anyone tried this?  Love
> to hear some details.
>
> O6. If anyone has any insights on how to disable redirects in Devise,
> I would love to hear more.  It really defeats the point of using ajax
> if my page is going to reload after any authentication action.
>
> O7. For dealing with browser http authentication pop-up, this link has
> good resources:http://groups.google.com/group/plataformatec-devise/browse_thread/thr...

Craig Buchek

unread,
Mar 26, 2011, 5:07:53 PM3/26/11
to Devise
The equivalent in jQuery (and plain old DOM) is
event.preventDefault(). Used the same way as Walter's example.

There are 2 reasons to prefer using the submit button with
preventDefault(). First, it can be styled like all the other submit
buttons. Second, if the user does not have JavaScript enabled, you can
still make it work by hitting the server as a normal form submission.

Cheers,
Craig
Reply all
Reply to author
Forward
0 new messages