Monday, January 29, 2007

Avoid database insert on page refresh using synchronizer(Deja vu) token pattern

I am writing the DAO (data access objects) for our web application and it is not done yet. I have not plugged-in any data duplication prevention logic and that means you can have duplicate rows in database. Now, duplicate row prevention is a topic in itself and a lot of time you do not want to plug it in because duplicate prevention is time consuming task. Doing a column by column comparison on a large table may not perform very well. Anyways that is not the main story. Main story is, my data API allow duplicate rows, so if a user re-submits some form page by clicking refresh button then we insert a duplicate row in database quite unintentionally.

We are using struts framework for page flows. Page refresh calls the data flushing action again and we want to prevent that. I did a bit of goggling around and looks like everyone is using "synchronizer token pattern" to avoid this problem. The scheme is following:

When a page is requested, generate a token and render this token as part of the page. (maybe as a hidden field). Store this same token in session using the page as key. when the page is submitted, you compare the token from page to the one stored in session, if both of them match then allow submit. If submit is successful then clear the token from session (using page as key).

Now, lets say the user hits refresh. The page still has the old token, so the token from page would not match the token in session and we do not allow submits. If user requests that page again through normal work flow then we re-generate a new token and everything is okay dokay ;o) if I am not feeling very lazy i will try this pattern with a simple form and servlet.

Struts has built in support for synchronizer tokens. Some useful links

© Life of a third world developer
Maira Gall