2011-01-06 17 views
12

मैं वापस/आगे या पृष्ठ को रीफ्रेश करके डुप्लिकेट फॉर्म सबमिशन को रोकने के लिए एक तकनीक के साथ आया था। और मैंने इसे यहां पर चर्चा करने के बारे में सोचा, मैंने पहले से ही एक नमूना का परीक्षण किया है जो उत्पादन वातावरण में नहीं है, आप किस दोष की पहचान कर सकते हैं?डुप्लिकेट फॉर्म सबमिशन को रोकना

कृपया ध्यान दें कि मैं फॉर्म टोकन का उपयोग करने के बारे में अच्छी तरह से जानता हूं, जो आपको सीएसआरएफ हमलों के खिलाफ बचाव करेगा, और नीचे दिए गए चरणों में नहीं जोड़ा गया था।

प्रत्येक प्रपत्र के लिए

-Generate फार्म आईडी, और के रूप में के रूप में छिपे हुए फ़ील्ड इसका इस्तेमाल:

$formid = microtime(true)*10000; 

- प्रपत्र पर प्रस्तुत: डेटा से

  • मान्य

  • फॉर्म फ़ील्ड डेटा के हैश की गणना करें

    $allvals = ''; 
    foreach($_POST as $k=>$v){ 
        $allvals .= $v; 
    } 
    $formHash = sha1($allvals); 
    
  • पहले सहेजे गए हैंश की तुलना करके फॉर्म हैश को मान्य करें। सत्र मान प्रत्येक फॉर्म को $ formid चर से बांध दिया जाता है।

    $allowAction = true; 
    if(isset($_SESSION['formHash'][$_POST['formid']]) && ($_SESSION['formHash'][$_POST['formid']] == $formHash)){ 
        $allowAction = false; 
    } 
    
  • यदि फॉर्म हैश नहीं मिला है, तो इसका मतलब है कि यह पहली बार सबमिट किया गया है या फॉर्म डेटा बदल दिया गया है।
  • डेटा (डेटाबेस के लिए उदाहरण के लिए,) को बचाया, तो सत्र के लिए प्रपत्र हैश को बचाने:

    $_SESSION['formHash'][$_POST['formid']] = $formHash; 
    

कोड के पूर्ण संस्करण: http://thebusy.me/2011/01/06/preventing-duplicate-form-submissions/

+0

'हैश स्निपेट को' $ formHash = sha1 (serialize ($ _ POST)) के विरुद्ध बेंचमार्क करने पर विचार करें; '। इसमें हैश कुंजी भी होगी, जो फायदेमंद हो सकती है या नहीं भी हो सकती है। – Dan

+0

संभावित रूप से संबंधित/डुप्लिकेट, http://stackoverflow.com/questions/4614052/how-to-prevent-multiple-form-submission-on-multiple-clicks-in-php/4614310#4614310 – user562374

+0

http: // के संभावित डुप्लिकेट /stackoverflow.com/questions/218907/how-to-handle-multiple-submissions-server-side –

उत्तर

7

एक आसान तरीका क्या हासिल करना आप सबमिट पर रीडायरेक्ट का उपयोग करना चाहते हैं। एक पोस्ट अनुरोध को संसाधित करने के बाद आप संभवतः उसी पृष्ठ पर रीडायरेक्ट करते हैं। यह एक सामान्य पैटर्न है जिसे "पोस्ट के बाद रीडायरेक्ट" या POST/Redirect/GET कहा जाता है।

उदाहरण के लिए:

<?php 
if($_POST) { 
    // do something 

    // now redirect 
    header("Location: " . $_SERVER["REQUEST_URI"]); 
    exit; 
} 
?> 

<html> ... 
<form method="post" action=""> ... </form> 

कार्रवाई की स्थापना करके "" तो यह अपने आप को प्रस्तुत करेगा करने के लिए, उस क्षण में अगर ($ _ पोस्ट) कोड ब्लॉक सच करने के लिए मान्य और फार्म पर कार्रवाई करेंगे, तो अनुप्रेषित खुद को वापस

बेशक आप शायद एक अलग पृष्ठ पर रीडायरेक्ट करना चाहते हैं जो "आपका फॉर्म सबमिट कर दिया गया है" प्रतिक्रिया दिखाता है या फ़ॉर्म को एक अलग पृष्ठ पर रखता है और इस पृष्ठ का HTML प्रतिक्रिया है।

इस विधि का लाभ यह है कि जब आप बैक बटन दबाते हैं तो यह एक GET अनुरोध करता है ताकि फ़ॉर्म पुनः सबमिट नहीं किया जा सके।

फ़ायरफ़ॉक्स पर, यह वास्तव में ब्राउज़र इतिहास से बाहर जमा हो जाएगा, इसलिए जब उपयोगकर्ता वेब पर ब्राउज़ करते हैं और फिर "धन्यवाद" पृष्ठ देखने के बजाय उन्हें वापस पृष्ठ पर देखते हैं, तो वे फॉर्म पेज देखते हैं।

+0

हां, मैंने इसके बारे में पढ़ा है, और मैं भविष्य की परियोजनाओं के लिए इसका उपयोग करूंगा। मुद्दा मेरी वर्तमान वेबसाइटों के लिए है, मैं फॉर्म टोकन का उपयोग कर रहा हूं, और मैं अन्य पृष्ठों पर रीडायरेक्ट करके कोड की संरचना को बदलना नहीं चाहता हूं। धन्यवाद @ newz2000 – isogashii

+1

आप धन्यवाद संदेश सक्षम करने के लिए एक कदम आगे भी जा सकते हैं। सेटअप 2 divs, फॉर्म के साथ एक और धन्यवाद संदेश के साथ एक। फिर प्रदर्शित करने के लिए धन्यवाद div सेट करें: सीएसएस में कोई भी नहीं। क्या रीडायरेक्ट formpage.php पर वापस जाएं? Thankyou = 1 अगर ($ _GET ['thankyou'] == 1) {css फॉर्म div को प्रदर्शित करने के लिए कोई भी नहीं है, और प्रदर्शित करने के लिए धन्यवाद सेट करें: ब्लॉक} – MSD

+5

यह मूर्खतापूर्ण होने के लिए फॉर्म टोकन के साथ संयुक्त होने की आवश्यकता है। यदि POST अनुरोध प्रगति पर है, तो उपयोगकर्ता रीफ्रेश या पुनः सबमिट करता है, तो आप डुप्लिकेट अनुरोध के साथ समाप्त होते हैं। – bcoughlan

1

ऐसा लगता है कि आप इसके साथ अत्यधिक जटिल हो रहे हैं।मेरा पसंदीदा तरीका है, क्योंकि यह भी कुछ ही समय में हैक्स जैकिंग सत्र से बचाता है, यहाँ वर्णित है:

http://www.spotlesswebdesign.com/blog.php?id=11

यह किसी भी रूप पर impliment करने के लिए सरल और आसान है। यह सत्यापित करने के लिए एक यादृच्छिक रूप से जेनरेट किया गया पृष्ठ इंस्टेंस आईडी का उपयोग करता है कि प्राप्त प्रपत्र सबमिट करने वाले अंतिम पृष्ठ के समान है जो उस विशेष उपयोगकर्ता को दिया गया है।

+2

उत्तर के लिए धन्यवाद, लेकिन, पोस्ट कहता है: "काम करने के लिए नया सत्र पृष्ठ इंस्टेंस आईडी सेट करने से पहले यह प्रपत्र प्रसंस्करण तर्क होना महत्वपूर्ण है हालांकि, इसके आसपास के तरीके हैं। " एक ही समय में दो पेज खोलने का प्रयास करें, पहला सबमिट करने से काम नहीं करेगा, क्योंकि दूसरा पेज खोला जाने पर नई पेज आईडी उत्पन्न होती है, यह इस तकनीक की कमजोरी है। लेकिन आप जेनरेट किए गए पेज आईडी के सरणी का उपयोग कर सकते हैं, और उनके खिलाफ जांच सकते हैं, और सरणी से मेल खाने वाले को हटा सकते हैं। – isogashii

+0

अच्छा बिंदु। सरणी एक अच्छा विचार है। – dqhendricks

+0

@isogashii मैंने सरणी-आधारित विधि को प्रतिबिंबित करने के लिए आलेख को संशोधित किया है। – dqhendricks

-1

उपरोक्त दोनों समाधान अच्छे हैं लेकिन थोड़ा सा है।

उसी उपयोगकर्ता से अगले कुछ मिनटों में डेटा में शायद मामूली परिवर्तन के साथ आगे सम्मिलन रोकने के बारे में कैसे?

यह उपयोगकर्ता मशीन पर एक कुकी में एमडी 5 हैश डालने और डेटाबेस में एक प्रतिलिपि संग्रहीत करके किया जा सकता है - इस तरह एक ही समय से उसी मशीन से आगे का प्रयास किसी भी समय पर अनदेखा किया जा सकता है और इसे डालने से रोक दिया जा सकता है डेटाबेस।

शायद कोई मेरे सुझाव की वैधता और प्रभावशीलता पर टिप्पणी कर सकता है या क्या मैं गलत पेड़ को भौंक रहा हूं ???

संबंधित मुद्दे