The code here shows that devise will redirect to the currently requested path when the session times out (which is checked and enforced by the timeoutable module) : https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L120
The attempted_path is set by warden before invoking the failure app.
Question is : Why would devise redirect back to the current requested path itself? If the session has timed out then shouldn't the client be redirected to the login page for the current entity (User or Admin or whatever)?
It does use the scope_url if attempted_path is not set. But I do not understand why should a redirect be made to the currently requested path again? Wouldn't this just result in a redirect-loop?
This redirect-loop is infact happening with Rails admin. If I enable timeoutable for the model for which I am authenticating in Rails admin, then after session timeout, any request will result in a redirect loop.
So can someone please explain to me why a redirect to attempted_path is being made at all? What use case doe sit serve?
Additional info Here are the two flows that I have in mind.
And it repeats into a loop until browser says "Website is not redirecting properly".
After a long "debugging weekend" I found out that the issue was because the Session and Cookie middlewares were placed after Warden in the rack stack.
My application is a Rails 5 API application, which means cookies and sessions are not available by default. Despite being an API app, I had to incorporate session / cookie based auth mechanism for certain reasons. So I manually added the two middlewares to the rack stack.
Since I added them in config/application.rb they got added almost at the far end of the stack, i.e. much after the Warden middleware itself. However the Warden middleware makes it very clear that it needs a Session and Cookie manager before it in the stack. That way any session changes it makes will get serialized into the session and the cookie eventually.
This resulted in the session changes done by the failure app being discarded. Because of that the session never got cleared and resulted in a redirect loop. The following steps will make it clearer.
Warden middleware bypassing all the intermediate middlewares it came through. So it misses the cookie and session middlewares)Steps 5-8 repeat until browser stops with an error.
Here is a sequence diagram I made capturing the whole flow for anyone interested in the details.

@Prometheous : Thank you for your comment. However one thing is still unclear to me :
In case of a timeout, what issues will be there if the FailureApp directly redirects to scope login url. You say :
Without the redirection to the attempted path, devise wouldn't know how to redirect to the sign in page.
But, can't it get it from the scope_url method which is used in the else part here : https://github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L128 ?
scope is known for sure.
What am I missing?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With