Jim Burgess
2009-Aug-26 15:02 UTC
How to stop a user submitting the same data more than once.
I have a standard form built with rails, which a user to my site can use to submit data. Unfortunately one user just managed to submit exactly the the same data three times in a row. From the server logs it seems as though he didn''t use his back button and then resubmit everything. It looks more like he got a bit fed up waiting for the form to process and pressed the submit button three times. However, I didn''t think this was possible in Rails. Is this correct? For the life of me I cannot reproduce this error, even by entering the exact same data the user did and pressing submit ten times in quick succession. Can anyone give me any tips on as to why this might have happened and what I can do to prevent this happening in future. Thanks in advance. -- Posted via http://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-26 15:06 UTC
Re: How to stop a user submitting the same data more than once.
Quick hit from google after using "disable form rails after click": http://railsforum.com/viewtopic.php?id=9585 Hope this helps. -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 15:09 UTC
Re: How to stop a user submitting the same data more than once.
Aldric Giacomoni wrote:> Quick hit from google after using "disable form rails after click": > http://railsforum.com/viewtopic.php?id=9585 > > Hope this helps.Cheers for the reply, but this is quick and dirty and doesn''t solve the problem if the user has javascript disabled. I would rather understand what is happening when submit is pressed and work things out from there. Would be grateful for any more suggestions. -- Posted via http://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-26 15:16 UTC
Re: How to stop a user submitting the same data more than once.
Jim Burgess wrote:> I would rather understand what is happening when submit is pressed and > work things out from there.In my very limited understanding of the web, this is what happens: 1) data is entered 2) ''submit'' is pressed 3) Asynchronous request is sent. If there is a way to make a form submit a synchronous request, as in, won''t be usable until the server comes back with "200 OK" or whatever a server does when it''s happy, then that''s probably what you want. -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 15:19 UTC
Re: How to stop a user submitting the same data more than once.
Thanks for the reply. I am still confused though, as to why I cannot reproduce the error. When I press submit ten times in quick succession then only one data set is submitted. -- Posted via http://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-26 15:23 UTC
Re: How to stop a user submitting the same data more than once.
Jim Burgess wrote:> Thanks for the reply. > I am still confused though, as to why I cannot reproduce the error. > When I press submit ten times in quick succession then only one data set > is submitted.Are you trying from the server? A computer on the same switch? On the same subnet? Remember, we''re dealing with packets here :) -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 15:33 UTC
Re: How to stop a user submitting the same data more than once.
No. I''m at home on my computer, the application is on a web server somewhere in Germany (as far as I know). I will however try to create the error from a different computer, see if that works. -- Posted via http://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-26 15:56 UTC
Re: How to stop a user submitting the same data more than once.
Jim Burgess wrote:> No. > I''m at home on my computer, the application is on a web server somewhere > in Germany (as far as I know). I will however try to create the error > from a different computer, see if that works.Can you reproduce the same kind of traffic surrounding the times when the user was doing the submit? It''s the blind leading the blind here, but I wonder if that may have to do with it.. -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 16:07 UTC
Re: How to stop a user submitting the same data more than once.
> It''s the blind leading the blind here,:-) It was last night and there was relatively little going on. I don''t think traffic is the problem. -- Posted via http://www.ruby-forum.com/.
Frederick Cheung
2009-Aug-26 16:15 UTC
Re: How to stop a user submitting the same data more than once.
On 26 Aug 2009, at 16:02, Jim Burgess wrote:> > I have a standard form built with rails, which a user to my site can > use > to submit data. Unfortunately one user just managed to submit exactly > the the same data three times in a row. > > From the server logs it seems as though he didn''t use his back button > and then resubmit everything. It looks more like he got a bit fed up > waiting for the form to process and pressed the submit button three > times.if the back action just fetched the page from the browser''s local cache you wouldn''t be able to tell.> > However, I didn''t think this was possible in Rails. Is this correct? >Nothing particular in rails to stop this (or rather it is a client side problem really - rails just sees 3 inbound requests) Fred> For the life of me I cannot reproduce this error, even by entering the > exact same data the user did and pressing submit ten times in quick > succession. > > Can anyone give me any tips on as to why this might have happened and > what I can do to prevent this happening in future. > > Thanks in advance. > -- > Posted via http://www.ruby-forum.com/. > > >
Patrick Doyle
2009-Aug-26 16:48 UTC
Re: How to stop a user submitting the same data more than once.
Is the user who caused the problem friendly or malicious? If (s)he is (or could be) malicious, then perhaps (s)he didn''t use a browser to create three records in your database, but instead wrote some code to post three times in quick succession. I just added a "sleep 5" to my #create method and tried using the "curl" utility to replicate your problem: curl -d"traveler[name]=z" http://localhost:3000/travelers ...but that failed because I didn''t set the authenticity token properly. I tried a few different things to figure out how to set it properly, but ultimately gave up and just commented out the #protect_from_forgery call in my application controller. Sure enough, I was able to fire off 3 of these curl commands in quick succession and create 3 new records. If I were of a much more malicious bent, I could probably figure out how to spoof the authenticity token. At this point, I was just trying to figure out an answer to "how could this happen?". If your user isn''t malicious and isn''t using some sort of automated HTTP screen scraping/updating utility, then I''ve just wasted your time making you read this. --wpd
Aldric Giacomoni
2009-Aug-26 17:45 UTC
Re: How to stop a user submitting the same data more than once.
Jim Burgess wrote:>> It''s the blind leading the blind here, > > :-) > > It was last night and there was relatively little going on. > I don''t think traffic is the problem.Well, then it''s time to sacrifice a goat. How long does it take once the button is pressed? Try pressing it once, then again after two-three seconds. Or try double-clicking, then double-clicking again. Remember -- users NEVER do things the way you expect them to, always the way THEY want to. -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 18:27 UTC
Re: How to stop a user submitting the same data more than once.
I have just finished entering the same data into IE and was rather surprised to see that I could submit it many times. So, it seems to be the case that Firefox 3.5 surpresses this behaviour, whilst IE lets you submit your data as many times as you want. Do you think it would be possible to stop this by using a session. In PHP I would do something like this: session_start(); if (!session_is_registered("counted")){ $query= insert_database(); session_register("counted"); } -- Posted via http://www.ruby-forum.com/.
Frederick Cheung
2009-Aug-26 18:42 UTC
Re: How to stop a user submitting the same data more than once.
On Aug 26, 7:27 pm, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> I have just finished entering the same data into IE and was rather > surprised to see that I could submit it many times. > So, it seems to be the case that Firefox 3.5 surpresses this behaviour, > whilst IE lets you submit your data as many times as you want. > > Do you think it would be possible to stop this by using a session. > > In PHP I would do something like this: > > session_start(); > if (!session_is_registered("counted")){ > $query= insert_database(); > session_register("counted"); >That won''t stop it because there is a window in between where you check and when you set the session variable (ie a race condition). Fred> } > > -- > Posted viahttp://www.ruby-forum.com/.
JL Smith
2009-Aug-26 19:00 UTC
Re: How to stop a user submitting the same data more than once.
They could have also hit the ''enter'' key multiple times too, not clicking anything. But in either case, a small amount of javascript will prevent this.
Greg Donald
2009-Aug-26 20:50 UTC
Re: How to stop a user submitting the same data more than once.
On Wed, Aug 26, 2009 at 10:09 AM, Jim Burgess<rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> I would rather understand what is happening when submit is pressed and > work things out from there.You can put a hidden field in your form, detect it and then set a session variable. Then don''t process any more forms when you detect the existence of the session variable. -- Greg Donald http://destiney.com/
Jim Burgess
2009-Aug-26 21:02 UTC
Re: How to stop a user submitting the same data more than once.
Cheers for the reply Fred. So how would one go about stopping this? Surely I cannot be the only one with this problem? -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-26 21:20 UTC
Re: How to stop a user submitting the same data more than once.
Lee Smith wrote:> They could have also hit the ''enter'' key multiple times too, not > clicking anything. > > But in either case, a small amount of javascript will prevent this.To prevent the submit button being pressed many times I am using <%= submit_tag "Submit", :onclick => "this.disabled = true" %> as kindly suggested by Aldric. How would I stop users pressing enter multiple times with java script. JS is really not my forte so i would be grateful for any advice -- Posted via http://www.ruby-forum.com/.
Mukund
2009-Aug-27 08:50 UTC
Re: How to stop a user submitting the same data more than once.
enter just processes the submit button. if you disable the submit button, then enter key press will be disabled as well. personally, i would get rid of the submit tag and use a image_submit_tag to get rid of stupid keyboard annoyances. This will force the user to click on the link to submit and you can do things like asking for confirmation or disabling it once pressed. On Aug 27, 2:20 am, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Lee Smith wrote: > > They could have also hit the ''enter'' key multiple times too, not > > clicking anything. > > > But in either case, a small amount of javascript will prevent this. > > To prevent the submit button being pressed many times I am using > <%= submit_tag "Submit", :onclick => "this.disabled = true" %> > as kindly suggested by Aldric. > > How would I stop users pressing enter multiple times with java script. > JS is really not my forte so i would be grateful for any advice > -- > Posted viahttp://www.ruby-forum.com/.
Jim Burgess
2009-Aug-27 09:29 UTC
Re: How to stop a user submitting the same data more than once.
Thanks for all of the answers. I solved it a little differently and will explain how in case a) it helps anybody else b) there is a flaw in my method which I have overlooked What I did was in the controller: Create a model object: @applicant = Applicant.new(params[:applicant]) Wait for a post request. Look up the last email address sucessfully stored in the database. Check if it is the same as the email address currently being submitted? If so, it is possible that someone has pressed submit twice, or used the back button in their browser. This can therefore be ignored and the user redirected to the success view. If the email adresses are not identical, check if @applicant can be saved. If it can, redirect to success, if it can''t re render index view. If the applicant is redirected to the success view without their data being saved (i.e. if both email addresses are the same), then they also receive a flash message that a double data entry was detected for their email address and that the record was only saved once. For this particular application it is not desired that people can apply twice and in practice it rarely happens. -- Posted via http://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-27 14:24 UTC
Re: How to stop a user submitting the same data more than once.
Good to hear that you''ve solved the problem yourself. Is now too late to point out that you could probably use validates_uniqueness_of in your model? http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002167 -- Posted via http://www.ruby-forum.com/.
Matt W.
2009-Aug-27 14:43 UTC
Re: How to stop a user submitting the same data more than once.
I have a similar problem that I''m working on, but I was going to take a slightly different approach. My problem is that I''m collecting completely anonymous data at first, but then I want people to be able to come in later and create an account, then hopefully be able to find their records. I''m not sure if this scenario is even realistic, but here is where I am at in my thinking so far… The user enters the initial data and their IP address is stored along with it (could this be my main downfall? I need to do more research on how these work and if they are truly unique for each user). When they come back (hopefully on the same computer!) and either try to enter the data again or go straight to making an account, I want to find a matching IP and validate that they are a returning user from the Model… then basically ask them if they''ve been here before, if so yada yada yada… This is still turning around in my brain and I have yet to do any research on it…but if anyone see''s any flaws in this method, feel free to let me know. Jim - it seems that if you can do your validation in the Model that would be better practice, but I''m not sure if that suits your needs. On Aug 27, 2:29 am, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Thanks for all of the answers. > I solved it a little differently and will explain how in case > a) it helps anybody else > b) there is a flaw in my method which I have overlooked > > What I did was in the controller: > Create a model object: @applicant = Applicant.new(params[:applicant]) > Wait for a post request. > Look up the last email address sucessfully stored in the database. > Check if it is the same as the email address currently being submitted? > > If so, it is possible that someone has pressed submit twice, or used the > back button in their browser. This can therefore be ignored and the user > redirected to the success view. > > If the email adresses are not identical, check if @applicant can be > saved. > If it can, redirect to success, if it can''t re render index view. > > If the applicant is redirected to the success view without their data > being saved (i.e. if both email addresses are the same), then they also > receive a flash message that a double data entry was detected for their > email address and that the record was only saved once. > > For this particular application it is not desired that people can apply > twice and in practice it rarely happens. > > -- > Posted viahttp://www.ruby-forum.com/.
Kyle F
2009-Aug-27 14:51 UTC
Re: How to stop a user submitting the same data more than once.
If you dont want duplicate data then just add the following to the model. Thats where validation should be. validates_uniqueness_of :email_address On Aug 27, 8:43 am, "Matt W." <m...-9Ukl6dVN2u9BDgjK7y7TUQ@public.gmane.org> wrote:> I have a similar problem that I''m working on, but I was going to take > a slightly different approach. > > My problem is that I''m collecting completely anonymous data at first, > but then I want people to be able to come in later and create an > account, then hopefully be able to find their records. I''m not sure > if this scenario is even realistic, but here is where I am at in my > thinking so far… > > The user enters the initial data and their IP address is stored along > with it (could this be my main downfall? I need to do more research on > how these work and if they are truly unique for each user). When they > come back (hopefully on the same computer!) and either try to enter > the data again or go straight to making an account, I want to find a > matching IP and validate that they are a returning user from the Model… > then basically ask them if they''ve been here before, if so yada yada > yada… > > This is still turning around in my brain and I have yet to do any > research on it…but if anyone see''s any flaws in this method, feel free > to let me know. > > Jim - it seems that if you can do your validation in the Model that > would be better practice, but I''m not sure if that suits your needs. > > On Aug 27, 2:29 am, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: > > > Thanks for all of the answers. > > I solved it a little differently and will explain how in case > > a) it helps anybody else > > b) there is a flaw in my method which I have overlooked > > > What I did was in the controller: > > Create a model object: @applicant = Applicant.new(params[:applicant]) > > Wait for a post request. > > Look up the last email address sucessfully stored in the database. > > Check if it is the same as the email address currently being submitted? > > > If so, it is possible that someone has pressed submit twice, or used the > > back button in their browser. This can therefore be ignored and the user > > redirected to the success view. > > > If the email adresses are not identical, check if @applicant can be > > saved. > > If it can, redirect to success, if it can''t re render index view. > > > If the applicant is redirected to the success view without their data > > being saved (i.e. if both email addresses are the same), then they also > > receive a flash message that a double data entry was detected for their > > email address and that the record was only saved once. > > > For this particular application it is not desired that people can apply > > twice and in practice it rarely happens. > > > -- > > Posted viahttp://www.ruby-forum.com/.
Jim Burgess
2009-Aug-27 15:36 UTC
Re: How to stop a user submitting the same data more than once.
Thanks for the replies. I''m also not sure if doing the validation in the model would work. Assuming that the user has a slow connection and hits submit on the form twice, then the first time the email would be unique, so everything would be good. However, would it not be the case that the second time the user presses submit, the record would have been stored, but the success screen would have not been displayed (hence them feeling the need to press submit a second time). In this case the email address would no longer be unique and an error would be thrown. So, potentially the user could think that their data had not been submitted, when in fact what they would be seeing was an error caused by their second submission (their first having been successful). Nonetheless, thank you very much for the link Aldric. It is definitely useful to understand what is happening behind the scenes in Active Record, and it elaborates on the race conditions Fred mentioned. I will have a play around with validates_uniqueness_of this evening. -- Posted via http://www.ruby-forum.com/.
Matt W.
2009-Aug-27 15:52 UTC
Re: How to stop a user submitting the same data more than once.
After talking to some friends of mine, the IP address is NOT a good idea...looks like I''ll be looking at a cookie solution instead. On Aug 27, 7:43 am, "Matt W." <m...-9Ukl6dVN2u9BDgjK7y7TUQ@public.gmane.org> wrote:> I have a similar problem that I''m working on, but I was going to take > a slightly different approach. > > My problem is that I''m collecting completely anonymous data at first, > but then I want people to be able to come in later and create an > account, then hopefully be able to find their records. I''m not sure > if this scenario is even realistic, but here is where I am at in my > thinking so far… > > The user enters the initial data and their IP address is stored along > with it (could this be my main downfall? I need to do more research on > how these work and if they are truly unique for each user). When they > come back (hopefully on the same computer!) and either try to enter > the data again or go straight to making an account, I want to find a > matching IP and validate that they are a returning user from the Model… > then basically ask them if they''ve been here before, if so yada yada > yada… > > This is still turning around in my brain and I have yet to do any > research on it…but if anyone see''s any flaws in this method, feel free > to let me know. > > Jim - it seems that if you can do your validation in the Model that > would be better practice, but I''m not sure if that suits your needs. > > On Aug 27, 2:29 am, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: > > > Thanks for all of the answers. > > I solved it a little differently and will explain how in case > > a) it helps anybody else > > b) there is a flaw in my method which I have overlooked > > > What I did was in the controller: > > Create a model object: @applicant = Applicant.new(params[:applicant]) > > Wait for a post request. > > Look up the last email address sucessfully stored in the database. > > Check if it is the same as the email address currently being submitted? > > > If so, it is possible that someone has pressed submit twice, or used the > > back button in their browser. This can therefore be ignored and the user > > redirected to the success view. > > > If the email adresses are not identical, check if @applicant can be > > saved. > > If it can, redirect to success, if it can''t re render index view. > > > If the applicant is redirected to the success view without their data > > being saved (i.e. if both email addresses are the same), then they also > > receive a flash message that a double data entry was detected for their > > email address and that the record was only saved once. > > > For this particular application it is not desired that people can apply > > twice and in practice it rarely happens. > > > -- > > Posted viahttp://www.ruby-forum.com/.
Aldric Giacomoni
2009-Aug-27 15:54 UTC
Re: How to stop a user submitting the same data more than once.
And maybe one more.. Again, I know you dislike javascript, but.. :) This isn''t exactly generic - I''m pulling it straight out of something I''m doing right now. Why not show a spinner (and disable the submit button?) when they press submit and hide the spinner when that''s done ? It''s all about the feedback, right? :) <%= image_tag("spinner.gif", :align => "absmiddle", :border => 0, :id => "spinner", :style =>"display: none;" ) %> </center> <%= observe_field :date, # The field to observe :with => :date, # The input to validate #:on => "onselect", # What action to check. With JS updates, use frequency. :frequency => 1, # The frequency in seconds to watch for changes :url => {:action => ''filter_widget'', :controller => ''dictated_exams'', :method => :post }, # The action to call when changes occur :update => :filter_counts, # Name of the <div> to update :before => "Element.show(''spinner'')", :success => "Element.hide(''spinner'')" %> -- Posted via http://www.ruby-forum.com/.
Jim Burgess
2009-Aug-27 16:03 UTC
Re: How to stop a user submitting the same data more than once.
That''s a cool idea. I will also have a play around with that this evening. Thank you very much. -- Posted via http://www.ruby-forum.com/.
Matt Jones
2009-Aug-27 17:15 UTC
Re: How to stop a user submitting the same data more than once.
The problem is that your users, like most users, are not very bright. They double-click (or in this case, triple-click) submit buttons. :disable_with will pretty much solve the issue; anybody with enough savvy to have JS disabled likely knows that you don''t double- click submit buttons. --Matt Jones On Aug 26, 11:09 am, Jim Burgess <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Aldric Giacomoni wrote: > > Quick hit from google after using "disable form rails after click": > >http://railsforum.com/viewtopic.php?id=9585 > > > Hope this helps. > > Cheers for the reply, but this is quick and dirty and doesn''t solve the > problem if the user has javascript disabled. > > I would rather understand what is happening when submit is pressed and > work things out from there. > > Would be grateful for any more suggestions. > -- > Posted viahttp://www.ruby-forum.com/.