Domanda

Qual è il modo migliore per impedire che un modulo venga rielaborato quando un utente preme un pulsante Indietro?

Sto seguendo il Pubblica / Reindirizza / Ottieni pattern , quindi Non ho problemi se si preme F5, ma il pulsante Indietro offre comunque l'opportunità di inviare nuovamente il modulo. Se questo modulo è una pagina di elaborazione della carta di credito, non va bene.

Questa domanda è stata posta in qualche modo qui , ma i termini e le risposte erano di scarsa qualità e non specifici di questo problema.

Ho form.php che si sottomette a se stesso. Se non si sono verificati errori nei dati di input al momento dell'invio, l'utente viene reindirizzato a form_thanks.php. Ritornare indietro (e " Invia " o " Reinvia ") una volta reinviato form.php (BAD!) E poi li riporta a form_thanks.php.

Se possibile, includi anche soluzioni che non comportano l'utilizzo di sessioni.

È stato utile?

Soluzione 2

Questo dovrebbe essere fatto con un token monouso, o un nonce . Il php / server dovrebbe includere questo token in un campo modulo nascosto.

Dovrebbe archiviare un elenco di tutti i token recenti e ogni volta che viene inviato un modulo, dovrebbe verificare se il token è nell'elenco dei token validi recenti.

Se non è nell'elenco, non rielaborare il modulo.
Se si trova nell'elenco, quindi elaborare il modulo e rimuovere il token dall'elenco.

I token possono essere gestiti all'interno di sessioni o solo una semplice tabella di database senza sessioni. I token dovrebbero essere specifici dell'utente però.

Questo è anche il modo consigliato per evitare CSRF .

Altri suggerimenti

Lo farei diversamente. Inserisci un input nascosto con una stringa casuale come valore e quando viene inviato archivia quella stringa casuale in una sessione. Imposta un semplice controllo per vedere se lo hanno già pubblicato e se non hanno accettato l'input.

Sto solo pensando ad alta voce qui. Ma che dire di una variazione su post / reindirizzamento / get in cui il get finale non è effettivamente il get finale;) Ma piuttosto, a sua volta, si inoltra sempre automaticamente alla pagina veramente finale, in modo che se l'utente preme il pulsante Indietro, ritornano proprio da dove sono venuti?

EDIT:

Ok, prendendo in considerazione il commento del PO, ecco un'altra idea. È possibile che l'URL per l'invio del modulo richieda un parametro valido per un solo utilizzo. Quel token sarebbe stato generato (usando MD5 o alcuni di questi) prima che il modulo fosse inviato e potesse essere archiviato in un database (in risposta al suggerimento di qualcun altro che hai richiesto una soluzione senza usare le sessioni). Dopo l'elaborazione del modulo, questo token verrà quindi contrassegnato nel database come già utilizzato. In modo che quando la pagina viene restituita con lo stesso token, è possibile adottare misure per impedire il reinvio dei dati del modulo al back-end.

Risposta tardiva, ma si potrebbe evitare del tutto l'elaborazione utilizzando una soluzione basata su AJAX; non ci sarebbe un problema con l'inclusione di un nonce con questo schema di elaborazione, ma utilizzando una query asincrona che, in caso di successo, reindirizza l'utente, le richieste non vengono ripetute aggiornando, premendo indietro o qualsiasi altra cosa che non faccia clic sul pulsante.

È anche facile implementare un meccanismo che impedisce al pulsante di essere premuto due volte o di essere "bloccato". se durante la richiesta è accaduto qualcosa incorporando nel gestore per la richiesta (sia ad alto livello con PrototypeJS o jQuery o basso livello con la tua funzione handrolled) i meccanismi per abilitare e disabilitare il pulsante quando la richiesta viene completata e vengono attivati, rispettivamente.

Trovo che back riporti il ??modulo nello stato in cui si trovava prima che la pagina fosse reindirizzata, in tal caso, ha un input / variabile nascosto o qualcosa che inizia con il valore dire true, quindi una volta inviato il modulo, e se il valore è true, modificalo in false e quindi invia, altrimenti restituisce false

Prova questo:

<SCRIPT type="text/javascript">
    window.history.forward();
</SCRIPT>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top