2017-04-17 99 views
0

我有一個CSRF預防的簡單標記,它在不使用AJAX提交時按預期工作。但是當使用AJAX時,它會一直顯示我創建的自定義錯誤。當使用AJAX提交表單時,CSRF令牌不起作用

這是我生成令牌功能:

function make_form_token() { 
    $token = base64_encode(openssl_random_pseudo_bytes(32)); 
    $_SESSION['token'] = $token; 
    return $token; 
} // end CSRF token generation 

的功能,然後調用名爲隱藏字段form_token

<form id="contact-form" method="post"> 
    <input type="hidden" name="form_token" value="<?php echo make_form_token(); ?>"> 

    <div class="col-sm-5 col-md-4 col-xs-6"> 
     <button id="send" type="submit" name="submit" class="btn btn--primary type--uppercase">Send Enquiry</button> 
    </div> 
</form> 

然後Ajax調用從PHP腳本接觸提交。 PHP

$(document).ready(function(){ 
    $("#send").click(function(){ 
     $("#send").prop("disabled", true); 
     $(".hideloader").show(); 
     $("#send").html("Sending <img src='img/ajax-loader.gif'>"); 

     var form_data = $("#contact-form").serialize(); 

     $.ajax({ 
      type: 'POST', 
      url: 'contact-submit.php', 
      data: form_data 
     }).done(function(response) { 
      $("#server-results").hide().html(response).fadeIn("slow"); 
      $("#send").prop("disabled", false); 
      $("#send").html("Send Enquiry"); 
     }); 
    }); 
}); 

接觸submit.php

if ($_SERVER["REQUEST_METHOD"] == "POST") { 

    $message = ""; 

    if (!isset($_SESSION['token']) || $_POST['form_token'] !== $_SESSION['token']) { 
     $message .= "There was an error submitting the form. Please try again later. <br/>"; 
    } 

    if ($message) { 
     echo "<div class='red-error'><b>There were errors in your form:</b> <br/>" . $message . "</div>"; 
    } else {  
     // send email etc. 
    } 
} 
+0

你能的var_dump $ _ POST [ 'form_token']和$ _SESSION [ '令牌']?他們是一樣的嗎? –

+0

當嘗試的var_dump我得到這個: 注意:未定義的變量:/應用程序/ MAMP/htdocs中/上線11 空字符串_SESSION(44) 「HBFYoXNsHS9WsBc7vds/MukXr0CR8pBFPc7WGi3JPvY =」 – Jonathan

+1

是您的會議開始時,POST請求到達服務器? –

回答

0

我想我知道你的問題是什麼。讓我知道如果我錯了。你有這樣的HTML:在頁面加載

<form id="contact-form" method="post"> 
<input type="hidden" name="form_token" value="<?php echo make_form_token(); ?>"> 
<div class="col-sm-5 col-md-4 col-xs-6"> 
<button id="send" type="submit" name="submit" class="btn btn--primary type--uppercase">Send Enquiry</button> 
</div> 
</form> 

生成此HTML,但我認爲這是對POST產生一樣,所以當您在form隨着有效form_token柱與該請求到達服務器,它會生成一個新的標記(當生成HTML時),將其存儲到$ _SESSION中,這與它在頁面加載時生成的標記不同。當且僅當您的請求是GET時,解決方案是生成form

編輯:確保當POST請求到達服務器時啓動會話。

EDIT2:這是你可以檢查你的請求是否是POST:

if ($_SERVER['REQUEST_METHOD'] === 'POST') { 
    // The request is using the POST method 
} 
+0

但我不明白爲什麼它不起作用。我一直使用這個不使用AJAX的表單,它可以100%工作。只有現在使用AJAX時,它給了我這個問題 – Jonathan

+0

@Jonathan我認爲你的HTML代碼覆蓋會話中存儲的令牌,在服務器接收到POST之後調用,然後它會比發佈值更經常。 –

+0

謝謝。如果你看我的原始帖子,我已經有POST檢查(我只有一個比你更少) if($ _SERVER ['REQUEST_METHOD'] =='POST'){ – Jonathan

相關問題