Grails 2 - Too many Ajax calls will invalidate user sesssion - ajax

*update: sorry, i didn't give a context. I'm using Grails 2.1.2 with the spring security plugin installed. Js lib -> jQuery (latest)
I have a page that submits lots of synchronous ajax calls (not my design, sorry). After the 25th call i see from firebug that i start getting http 302 status, then the handler for ajax calls when there's no user session is called (loing/authAjax in my case). My particular handler sends an http 401. In any case why is the session expiring? This happens only when i submit tons of synchronous ajax calls. Is there any limit to the number of ajax calls? Is it documented anywhere? Making async calls is not an option in this case because these ajax calls make db updates on the same table and that would result in a hibernate lock exception.
I'm not asking for a fix, i know how to fix this (by doing one single ajax call). What i'm asking is why the session is being invalidated? Any ideas?

Did you try to set the cache setting to false in your calls with jQuery ?
302 means you're getting data from the browser cache instead of the server.
Hope this help....

Related

Writing cookies on Rails besides the controller, possible?

I'm working on an application stack that has a rather particular architecture. The forms component is loaded on a view, and when the action is submitted, an async call using sidekiq is performed. This calls an endpoint that validates the form data, but none of this is returned back to the server and after this process is fired, there is a redirect to another page.
We want to add cookies to write the status of this call sidekiq did. This is not possible to do on the controller as the controller when it is rendering the destination page has no knowledge of this event that occurred. The possibility of writing this cookie on the async callback is tempting but this is not done on the controller (The controller loads a class that contains a module with this functionality)
Question: Is it possible to write cookies in places not in the controller, such as classes or models? I'm assuming no, but I figured it might be an interesting question.
It's not possible. Writing a cookie is a part of HTTP response, so you need to be in the request-response cycle, i.e. in the controller.
What you could do (and I did that more than once) is to have some kind of record in the database, storing a status of a background job, and from the page you redirected to periodically poll some endpoint with AJAX (or establish a Websocket connection) to check if the job has finished and with what status. Then you'll be able to set the cookie.

Scraping a website made with ICEfaces (session expired on consecutive ajax POST requests)

I'm trying to scrape a website created with the ICEfaces web framework via a node.js script. I've managed to handle the login just fine, and then get some data from the main page (namely ice.session and ice.view, along with the JSESSIONID cookie returned by the login response).
The problem I've run into is when I try to do an AJAX POST request to the /block/ URLs. If I do the request by itself, it returns some data (just not the data I need), but if I do it after any other request, I get <session-expired/> as a result. It doesn't even matter which of the ICEfaces /block/ URLs I send the request to (I've tried with /send-receive-updates, /dispose-views, and even /ping). I've even tried the same request twice in a row just for kicks, and I always get a <session-expired/> response in return on the second one. I've monitored the requests when I browse the page with Chrome, and as far as I know I'm sending all the correct form data (as well as the correct headers). The page works just fine when I load it in the browser, so there must be something I'm not doing right.
Apparently, the order in which you do the requests matters in ICEfaces (i.e. it's not stateless, which kind of makes sense I guess). I just moved the requests around and finally got the response I desired.
IceWindow, IceView and ViewState
Need to be passed as a parameter whenever you do an ajax submit.
Managed bean takes the previous instance of the current view view using ViewState value.

does post-redirect-get need to happen for an ajax request?

is there any reason to use the post-redirect-get (prg) for a request that you know will only happen via an ajax request?
in this scenario, you might have a request that is sent (either via ajax or direct), and we're assuming on the back-end we can distinguish which is which. In the case where the direct request is handled using prg, is there any reason to also handle the ajax request with a prg too?
or can an ajax post just be responded to directly?
For something that only uses AJAX, I can't see a reason to use prg. Since it is not a user controlled action with the possibility of duplication, the only way the AJAX call would be duplicated is if the original page was refreshed before the action finished, and since prg has that same one flaw, you may as well use the direct approach.

Ajax Status/Response Data from Primefaces

We are using Primefaces 2.x and Mojarra. We are trying to handle one particular case where you log into our site and then delete all of the cookies. Then click on a menu option. What we would like to have happen is for the user to be redirected to our login screen. The problem is that we are not using the "url" attribute, so Primefaces does a partial-page ajax call. Which returns an empty response.
At this point, without a Session Id there is no session. So, on the server we are in the midst of an Ajax call without a session. If I try and do a sendRedirect it sends a 302 to the browser, but either Primefaces or the browser is ignoring it because it is part of an Ajax call.
So, what I would like to do is to put a listener on the Ajax response and look for a 302 or a change in the location. However, I can't find a way to use the jsf.ajax.addOnEvent. It seems that Primefaces is not using the standard JSF Ajax calls. I looked at the AjaxStatus but all it gives me is events, no DATA and no access to the data.
I thought I could look for the JSESSIONID cookie, which the user has deleted, but when I use Javascript to print the cookies, the session id isn't printed.
So, I don't seem to be able to do a response.sendRedirect in a Session Filter because I am in the midst of an Ajax call. And I can't detect on the client that I need to redirect the user, which I could do if I knew it was required. And I can't seem to get any info out of Primefaces Ajax response.
By menu you mean the p:menuItem component, right? Assuming you're using the action attribute to call a method in your managed, try using the attribute ajax="false". I use that and it works well for me.

Can you reliably set or delete a cookie during the server side processing of an Ajax (XHR) call?

I have done a bit of testing on this myself (During the server side processing of a DWR Framework Ajax request handler to be exact) and it seems you CAN successfully manipulate cookies, but this goes against much that I have read on Ajax best practices and how browsers interpret the response from an XmlHttpRequest. Note I have tested on:
IE 6 and 7
Firefox 2 and 3
Safari
and in all cases standard cookie operations on the HttpServletResponse object during Ajax request handling were correctly interpreted by the browser, but I would like to know if it best practice to push the cookie manipulation to the client side, or if this (much cleaner) server side cookie handling can be trusted.
I would welcome answers both specific to the DWR Framework and Ajax in general.
XMLHttpRequest always uses the Web Browser's connection framework. This is a requirement for AJAX programs to work correctly as the user would get logged out if the XHR object lacked access to the browser's cookie pool.
It's theoretically possible for a web browser to simply share session cookies without using the browser's connection framework, but this has never (to my knowledge) happened in practice. Even the Flash plugin uses the Web Browser's connections.
Thus the end result is that it IS safe to manipulate cookies via AJAX. Just keep in mind that the AJAX call might never happen. They are not guaranteed events, so don't count on them.
In the context of DWR it may not be "safe".
From reading the DWR site it says:
It is important that you treat the HTTP request and response as read-only. While HTTP headers might get through OK, there is a good chance that some browsers will ignore them.
I've taken this to mean that setting cookies or request attributes is a no-no.
Saying that, I have code which does set request attributes (code I wrote before I read that page) and it appears to work fine (apart from deleting cookies which I mentioned in my comment above).
Manipulating cookies on the client side is rather the opposite of "best practice". And it shouldn't be necessary, either. HttpOnly cookies weren't introduced for nothing.

Resources