0

My problem is this.

When a user opens two tabs and goes to the same page that requires authentication it's all fine. If then he signs out in on of the tabs he obviously is redirected to the sign in page, not on the other tab, though. Which still is normal.

However, there are some functions on the page that use javascript and, if the user tries on of them he can't preform the action and there is a "sign_in.json" rendered that contains an devise error message "unauthenticated". I need to redirect the user to sign in form once this message in sent. How do I do that?

radical_edo
  • 934
  • 2
  • 11
  • 29
  • If i understand correctly you want to redirect the user after the devise error message "unauthenticated" is shown? – Deej Jun 16 '13 at 13:03
  • Sort of. I know about this message just because I see it under the web browser's console (Network tab). The message is not displayed to the user. It would have been displayed if he was redirected to the sing in page. Also the server logs show the `401 Unauthorized` – radical_edo Jun 16 '13 at 13:16
  • My understanding of `401 Unauthorized` is that this happens when authentication is required and has failed or has not yet been provided. Further to this it sounds like you want to override the the redirect inside the devise sessions controller I believe – Deej Jun 16 '13 at 13:20
  • I just stumbled on something i think should do the trick, but hasn't, yet. Extend `Devise::FailureApp` and overwrite some of the methods `respond` and `redirect_url` shown in here: [link](http://stackoverflow.com/questions/5832631/devise-redirect-after-login-fail). Dunno if I'm on the right track. – radical_edo Jun 16 '13 at 13:27
  • In addition to the link you provided you may want to have a look at the following also - http://stackoverflow.com/questions/6240141/devise-redirect-on-sign-up-failure – Deej Jun 16 '13 at 13:30

2 Answers2

0

It sounds like you use javascript to make a ajax request, to your server that responds with a 401 and some json data, right? If you use jQuery, can you do something like this:

# Your ajax call
$.ajax({
  ...
  statusCode: {
    401: function() {
      # Redirect to login
      window.location.replace("http://yoursite.com/login_page");
    }
  }
});

Edit: global ajax setting

You can globally change this behaviour for all ajax request in jQuery by using ajaxSetup like this:

$.ajaxSetup({
  statusCode: {
    401: function() {
      # Redirect to login
      window.location.replace("http://yoursite.com/login_page");
    }
  }
});

However the jQuery documentation strongly recommmend against this aproach, as this can break the intended behaviour of other plugins etc. Personally i think it would be fine in this example, just be sure what you do and test that everything works as expected. You can read more here: http://api.jquery.com/jQuery.ajaxSetup/

jokklan
  • 3,520
  • 17
  • 37
  • Yes. There are quite a lot of ajax requests on the page (front-end is written in Backbone). The 401 is rendered by devise (to my understanding), thought I can make it global by adjusting that gem. But it seems I need to find every ajax request and add error handling? Or can I make some sort of global `try/catch`?? – radical_edo Jun 16 '13 at 15:44
  • Also, I've managed to send a redirect to sing in page thanks to my tweaking of devise setup. However, this operation is cancelled... – radical_edo Jun 16 '13 at 16:02
  • I have added how to change this globally for all jQuery ajax requests :) – jokklan Jun 16 '13 at 22:05
0

@jokklan

your post was extremely helpful, I did change the global ajax setup, seems to be working fine. Also just had to send a response with 401 code.

This I managed by customizing the Devise::FailureApp

def respond
  # ...
  elsif request.xhr?
    redirect_to some_path, status: 401
  end
  # ...
end

Since the controller responds to json, the redirect happend also in json, but by setting the status as 401 I was able to catch that and redirect the user to the path I need with ajaxSetup

Not the prettiest, but I am open to suggestions on make it better.

radical_edo
  • 934
  • 2
  • 11
  • 29