Re: Preventing duplicate signups
Haven't had enough time for my previous reply to make it back to me so I could reply to it If using SQL, you might be able to do row or table locking to get around any race conditions. "Rob Bloodgood" <[EMAIL PROTECTED]> wrote: >> A really simple trick would be rather than to use a cookie, if >> you are saving state to DB anyway. Set a flag in the DB and test >> for its existence. >> >> sub handler{ >> >> my $s = session->new(); >> $s->continue(); >> >> my $flag = $s->get('flag'); >> if($flag){ >> # do something else >> } >> else{ >> # run insert for new signup >> } >> >> } -- James Smith <[EMAIL PROTECTED]>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix
Re: Preventing duplicate signups
"Rob Bloodgood" <[EMAIL PROTECTED]> wrote: >> A really simple trick would be rather than to use a cookie, if >> you are saving state to DB anyway. Set a flag in the DB and test >> for its existence. >> >> sub handler{ >> >> my $s = session->new(); >> $s->continue(); >> >> my $flag = $s->get('flag'); Be careful of race conditions. If things are timed right, two requests could run in parallel with just enough time differential to get around this test. You may want to see if there is a way to lock on something so this code section is serialized for any particular user. If you're using a web farm, good luck. Otherwise, either shared memory or a file link should be sufficient (non-NFS). >> if($flag){ >> # do something else >> } >> else{ >> # run insert for new signup >> } >> >> } -- James Smith <[EMAIL PROTECTED]>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix
Re: Preventing duplicate signups
On Thu, 17 May 2001, Rob Bloodgood wrote: > So, like many of you, I've got a signup system in place for bringing on new > customers. > > My signup script is reasonably straightforward. I use CGI::Validate to make > my parameters pass muster (along with a little judicious JavaScript on the > signup form), Apache::Session::Oracle to maintain state between the multiple > pages of the signup, CGI::FastTemplate to print a pretty success page, and > DBI to create the account records at successful creation. When you send out the signup form, include a random 32-character hexadecimal string as a hidden input, and record in your database that the code has been sent out. When the form is submitted, ensure that the code which accompanies it is valid, by looking in the database. Then mark the code as already used. When the user reloads, your program will see that the code he is sending was sent before, and can ignore his duplicate request. Jeffrey
Re: Preventing duplicate signups
Hi Rob, On Thu, 17 May 2001, Rob Bloodgood wrote: > But it doesn't work. I still get duplicate accounts, and I'm at a loss [snip] > Suggestions? As you're using Oracle, why not use a constraint? 73, Ged.
Re: Preventing duplicate signups
Rob Bloodgood wrote: > > So, like many of you, I've got a signup system in place for bringing on new > customers. > > My signup script is reasonably straightforward. I use CGI::Validate to make > my parameters pass muster (along with a little judicious JavaScript on the > signup form), Apache::Session::Oracle to maintain state between the multiple > pages of the signup, CGI::FastTemplate to print a pretty success page, and > DBI to create the account records at successful creation. > > At one time it was straight CGI but I've since updated it for mod_perl. > > Anyway, my only problem is that I can't seem to prevent duplicate signups, > e.g. reloading the last page to create multiple accounts. > > This is my dupe detection code: > > if (my (%post) = cookie('Signup')) { > local $^W = 0; > my $match = 0; > foreach (qw/ email url password / ) { > $match++ if param($_) and $post{$_} eq param($_) > } > if ($match == 3) { > # I tried this first, but some browsers are stupid. > # print header(-status=>'204 No Content'); > print header(-status=>'304 Not Modified'); > exit; > } > } > > Naturally, I set the corresponding cookie in the Header of the "Thank you > for signing up" template output. > > But it doesn't work. I still get duplicate accounts, and I'm at a loss as > to how to attack this problem. (this is the 3rd or 4th approach I've > tried). > > Suggestions? > > TIA! > > L8r, > Rob > > #!/usr/bin/perl -w > use Disclaimer qw/:standard/; i might suggest making your database use stronger indexing to prevent duplicate data in the database that way the db would throw an error that could be caught we use first name last name and email address to create a combined index that seems to do fine
RE: Preventing duplicate signups
> A really simple trick would be rather than to use a cookie, if > you are saving state to DB anyway. Set a flag in the DB and test > for its existence. > > sub handler{ > > my $s = session->new(); > $s->continue(); > > my $flag = $s->get('flag'); > if($flag){ > # do something else > } > else{ > # run insert for new signup > } > > } There should be a word for this... 2 minutes after I finished sending my post, I realized exactly this thing. Since I'm already accessing the DB w/ Apache::Session, I get miscellaneous flags thrown in for free... since the rest of the signup scripts only uses the hash keys in %session that it knows about. So, after a successful signup (read, creation of the new account record in the database), I simply stash the new acctid into %session: $session{id} = $id; Now here's the fun part. While writing this script originally, I put in a debug statement like so: # bypass SQL activity goto TEMPLATE if $ENV{REMOTE_ADDR} eq $my_ip and $session{email} ne $my_email; So the next time a signup comes in, I can check for the existence of $session{id}. If it exists... well, read the updated code: goto TEMPLATE if exists $session{id} or $ENV{REMOTE_ADDR} eq $my_ip and $session{email} ne $my_email; Since the template gets the rest of its values straight from %session anyway, the only other change I had to make was s/$id/$session{id}/. Problem solved! Now, of course, I have to provide for the previous behavior whereby a person could validly sign up multiple accounts if they were pointing to different urls, but hey! I've nailed the PROBLEM. Now I just have to adjust the behaviors slightly. L8r, Rob
Re: Preventing duplicate signups
Once your signup engine is ready to perform all database entries, have it set and commit a flag in the session indicating that it is processing. Once the signup process is complete, set a flag in the session indicating this as well. You must now add two tests to your signup engine to avoid dupes. The two previous flags should be inspected immediately after fetching the session (before processing anything) 1) to look for the completed flag which can just display/redisplay the final status of the signup, 2) to display a processing message while waiting for the previous signup process to complete (if processing but not completed) then gathering the completed data from the session and displaying the signup results. There are a few ways to go about #2, so be creative. Thanks, Tim Tompkins -- Staff Engineer / Programmer http://www.arttoday.com/ -- - Original Message - From: "Rob Bloodgood" <[EMAIL PROTECTED]> To: "mod_perl" <[EMAIL PROTECTED]> Sent: Thursday, May 17, 2001 10:42 AM Subject: Preventing duplicate signups > So, like many of you, I've got a signup system in place for bringing on new > customers. > > My signup script is reasonably straightforward. I use CGI::Validate to make > my parameters pass muster (along with a little judicious JavaScript on the > signup form), Apache::Session::Oracle to maintain state between the multiple > pages of the signup, CGI::FastTemplate to print a pretty success page, and > DBI to create the account records at successful creation. > > At one time it was straight CGI but I've since updated it for mod_perl. > > Anyway, my only problem is that I can't seem to prevent duplicate signups, > e.g. reloading the last page to create multiple accounts. > > This is my dupe detection code: > > if (my (%post) = cookie('Signup')) { > local $^W = 0; > my $match = 0; > foreach (qw/ email url password / ) { > $match++ if param($_) and $post{$_} eq param($_) > } > if ($match == 3) { > # I tried this first, but some browsers are stupid. > # print header(-status=>'204 No Content'); > print header(-status=>'304 Not Modified'); > exit; > } > } > > Naturally, I set the corresponding cookie in the Header of the "Thank you > for signing up" template output. > > But it doesn't work. I still get duplicate accounts, and I'm at a loss as > to how to attack this problem. (this is the 3rd or 4th approach I've > tried). > > Suggestions? > > TIA! > > L8r, > Rob > > #!/usr/bin/perl -w > use Disclaimer qw/:standard/; > > >
Preventing duplicate signups
So, like many of you, I've got a signup system in place for bringing on new customers. My signup script is reasonably straightforward. I use CGI::Validate to make my parameters pass muster (along with a little judicious JavaScript on the signup form), Apache::Session::Oracle to maintain state between the multiple pages of the signup, CGI::FastTemplate to print a pretty success page, and DBI to create the account records at successful creation. At one time it was straight CGI but I've since updated it for mod_perl. Anyway, my only problem is that I can't seem to prevent duplicate signups, e.g. reloading the last page to create multiple accounts. This is my dupe detection code: if (my (%post) = cookie('Signup')) { local $^W = 0; my $match = 0; foreach (qw/ email url password / ) { $match++ if param($_) and $post{$_} eq param($_) } if ($match == 3) { # I tried this first, but some browsers are stupid. # print header(-status=>'204 No Content'); print header(-status=>'304 Not Modified'); exit; } } Naturally, I set the corresponding cookie in the Header of the "Thank you for signing up" template output. But it doesn't work. I still get duplicate accounts, and I'm at a loss as to how to attack this problem. (this is the 3rd or 4th approach I've tried). Suggestions? TIA! L8r, Rob #!/usr/bin/perl -w use Disclaimer qw/:standard/;