Re: [PHP] Separation between View and State (The Back Button)
That will work fine. The other suggestion half-remembered by a previous poster is to do a header("Location: ") after you process the post, so that their "Back" button doesn't take them through the POST again. However, a user who is intentionally playing with the submit, forward, and back buttons can quickly prove that this is prone to error. header("Location: ") also comes with a great deal of subtle issues such as session cookie problems and HTTP connection waste. I personally prefer the unique token approach. YMMV On Thu, July 13, 2006 1:27 pm, Michael B Allen wrote: > Let's say you have a "Buy" button that posts a form to a script that > inserts or increments the quantity of a record in a shopping cart > table. So you click "Buy" and then "Checkout". Now if you hit the Back > button it asks the user if they would like to repost the form. If you > click "Ok" the db script runs again and now they have two items in the > cart. Not good. > > It seems to me this is a fundamental model view controller kind of > problem. There's no seperation between the view and the controller. > > What I'm thinking is that I need to give each form a unique token. > When > the form is submitted a new token is generate. So if at any time a > form > is reposted the token will be invalid and action regarding the form > contents can be igored. > > Specifically I'm thinking of somthing like: > > function token_generate() { > return $_SESSION['state_token'] = rand(1,9); > } > function token_matches() { > return isset($_POST['t']) && $_SESSION['state_token'] == > $_POST['t']; > } > if (token_matches()) { > // insert or update cart contents > } > ?> > > Shopping Cart > > >echo " . "\"/>\n"; > ?> > > // display cart contents > > I don't get to do much web programming so I'm wondering what the PHP > crowd thinks of this method. Can anyone improve on this? Is it fatally > flawed? How would you solve this problem in general? > > Thanks, > Mike > > -- > Michael B Allen > PHP Extension for SSO w/ Windows Group Authorization > http://www.ioplex.com/ > > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > > -- Like Music? http://l-i-e.com/artists.htm -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Separation between View and State (The Back Button)
At 11:27 AM 7/13/2006, Michael B Allen wrote: Let's say you have a "Buy" button that posts a form to a script that inserts or increments the quantity of a record in a shopping cart table. So you click "Buy" and then "Checkout". Now if you hit the Back button it asks the user if they would like to repost the form. If you click "Ok" the db script runs again and now they have two items in the cart. Not good. It seems to me this is a fundamental model view controller kind of problem. There's no seperation between the view and the controller. What I'm thinking is that I need to give each form a unique token. When the form is submitted a new token is generate. So if at any time a form is reposted the token will be invalid and action regarding the form contents can be igored. Perhaps, but I'll bet that a lot of re-posts will be from people who click, realize they forgot to change the quantity or another value, and back up in order to correct their mistake. You might consider accepting the most recent post, not the first, when the form token matches. You might also want to include a current timestamp in the form so that you can easily detect the sequence of multiple posts. One technique that might help is to insert a processing script between input form & output page. The form posts to the script which doesn't download anything to the browser but instead redirects to the destination page, so backing up from the destination doesn't automatically prompt for a re-post; the user would actually have to return to the form and re-submit it manually. And of course that's going to happen, too, so your underlying engine will need to be smart enough to know how to deal with multiple buy requests for the same product in any case. Regards, Paul -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Separation between View and State (The Back Button)
On Thu, 13 Jul 2006 14:41:21 -0400 Jim Moseby <[EMAIL PROTECTED]> wrote: > > > > Let's say you have a "Buy" button that posts a form to a script that > > inserts or increments the quantity of a record in a shopping cart > > table. So you click "Buy" and then "Checkout". Now if you hit the Back > > button it asks the user if they would like to repost the form. If you > > click "Ok" the db script runs again and now they have two items in the > > cart. Not good. > > > ::snip:: > > Someone posted here an elegant way of handling that, but I can't remember > who or the specifics of how. But, IIRC, it involved a header you can send > that keeps the page from being included in the browser history. So when the > user hits 'Back', it skips the processing page and takes them back to the > form page. Actually what would be even better is if there were a header that indicated the form data should NOT be reposted on back or reload. Anyone heard of such a thing? Mike -- Michael B Allen PHP Extension for SSO w/ Windows Group Authorization http://www.ioplex.com/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Separation between View and State (The Back Button)
Michael B Allen wrote: > Let's say you have a "Buy" button that posts a form to a script that > inserts or increments the quantity of a record in a shopping cart > table. So you click "Buy" and then "Checkout". Now if you hit the Back > button it asks the user if they would like to repost the form. If you > click "Ok" the db script runs again and now they have two items in the > cart. Not good. > > It seems to me this is a fundamental model view controller kind of > problem. There's no seperation between the view and the controller. > > What I'm thinking is that I need to give each form a unique token. When > the form is submitted a new token is generate. So if at any time a form > is reposted the token will be invalid and action regarding the form > contents can be igored. > > Specifically I'm thinking of somthing like: > > function token_generate() { > return $_SESSION['state_token'] = rand(1,9); > } > function token_matches() { > return isset($_POST['t']) && $_SESSION['state_token'] == $_POST['t']; > } > if (token_matches()) { > // insert or update cart contents > } > ?> > > Shopping Cart > > >echo " "\"/>\n"; > ?> > > // display cart contents > > I don't get to do much web programming so I'm wondering what the PHP > crowd thinks of this method. Can anyone improve on this? Is it fatally > flawed? How would you solve this problem in general? this is pretty much *the* way to tackle this issue. plenty of [minor] variations of your basic concept have been proposed as a solution to the back button problem on this list... the most notable difference being increased randomness in the token and keeping an array of valid tokens (e.g. how many forms will a user request before post'ing one of them?) and binding a given token to a given form (and/or data input 'type') > > Thanks, > Mike > -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Separation between View and State (The Back Button)
> > Let's say you have a "Buy" button that posts a form to a script that > inserts or increments the quantity of a record in a shopping cart > table. So you click "Buy" and then "Checkout". Now if you hit the Back > button it asks the user if they would like to repost the form. If you > click "Ok" the db script runs again and now they have two items in the > cart. Not good. > ::snip:: Someone posted here an elegant way of handling that, but I can't remember who or the specifics of how. But, IIRC, it involved a header you can send that keeps the page from being included in the browser history. So when the user hits 'Back', it skips the processing page and takes them back to the form page. Maybe a quick STFA will turn up something. JM -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php