2012-11-29 149 views
1

我有一個提交表單的php頁面。
我想添加一個支票,我可以停止基本的跨站點僞造。防止欺騙形式

我的代碼:

<?php 
session_start(); 

(...) //some code 

$secret = substr(md5(uniqid(rand(), true)), 1, 2); 
$_SESSION["secret"] = $secret; 
$auth = $secret; 

?> 

(...) 

<form id="form" name="form" action="<?php echo htmlentities($_SERVER[PHP_SELF]); ?>" method="post"> 

(...) 

<input type="hidden" name="id" value="<? echo $auth; ?>" /> 

(...) 

<?php 

(...) 

//as a debug I just tried to display 
echo $_POST["id"]; 
echo "="; 
echo $_SESSION["secret"]; 

(...) 

?> 
<div> 
</body> 
</html> 

但兩者idsecret永遠不會返回相同的值。
這是爲什麼?我錯過了什麼?


UPDATE

所以,我想在這裏由塞繆爾·庫克的回答一樣,也由Jon斯特林的評論所說:

if(!isset($_SESSION["secret"])){ 
    $secret = substr(md5(uniqid(rand(), true)), 1, 2); 
    $_SESSION["secret"] = $secret; 
    $auth = $secret; 
} 

但現在如果沒有$_SESSION["secret"]
該頁返回:

<input type="hidden" name="id" value="" /> 

我明白爲什麼,因爲祕密只有在會話變量存在時才被設置。
有什麼建議嗎?


UPDATE

移動的檢查產生一個新的會話密鑰之前,如果有ID的職位是隻檢查。 現在效果很好謝謝。

+0

是因爲您在頁面頂部重新生成$ secret並將其分配給會話? –

回答

0

在當調試代碼執行點,這個祕密已經改變:

echo $_POST["id"]; // previous secret 
echo "="; 
echo $_SESSION["secret"]; // new secret 

只要你做你檢查在腳本的開始(之前的比賽產生下一個祕密)它會沒事的。

+0

明白了。謝謝 :) – madziikoy

0

一旦你打開一頁$ auth將提交後$ _SESSION [「祕密」]將生成和我將在隱藏字段將改變,因爲$祕密將生成新的密鑰,但$ _POST ['id']是舊的一個來自Post方法。

+0

啊,我想我應該只生成一個新的會話密鑰,如果ID不存在? – madziikoy

+0

是 if(empty($ _ POST ['id'])){ //生成新密鑰 } –

0

您總是會生成一個新的$secret,因此它總是會有所不同。您可以檢查$_SESSION['secret']是否存在,如果不存在,則創建一個新變量。喜歡的東西:

if(!isset($_SESSION["secret"])){ 
    $secret = substr(md5(uniqid(rand(), true)), 1, 2); 
    $_SESSION["secret"] = $secret; 
    $auth = $secret; 
}