2011-04-05 48 views
0

我編寫了以下三個函數以防止會話劫持。他們工作。我在腳本的開頭調用了set_auth_token。然後在html窗體中調用get_auth_token。表單發佈後,我打電話給check_auth_token。但是,有時在用戶填寫表單後,他們填寫不正確,他們往往按F5 /刷新。這會導致頁面「死亡」。在表單填寫之前不會發生這種情況。當用戶刷新頁面時,表單令牌不匹配

我該怎麼做才能改進這些功能,以便每次用戶按下刷新時都不會死亡?

function set_auth_token() 
{ 
    if (!isset($_SESSION['auth_token'])) 
    { 
     $_SESSION['auth_token'] = hash('sha256',rand().time().$_SERVER['HTTP_USER_AGENT'].$_SERVER['REQUEST_URI']); 
    } 
} 

get_auth_token總是叫set_auth_token調用後,因此,如果它不能找到一個身份驗證令牌死亡:

function get_auth_token() 
{ 
    if (isset($_SESSION['auth_token'])) 
    { 
     return $_SESSION['auth_token']; 
    } 
    else 
    { 
     die('"No auth token."'); 
    } 
} 

引起頁面死的功能:

function check_auth_token() 
{ 
    if (array_key_exists('auth_token', $_SESSION) && array_key_exists('auth_token', $_POST)) 
    { 
     if ($_SESSION['auth_token'] == $_POST['auth_token']) 
     { 
     $_SESSION['auth_token'] = hash('sha256', rand() . time() . $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REQUEST_URI']); 
     } 
     else 
     { 
     die('Woah! It seems like you pressed Refresh (or Back/Forward). Just click here to sort it out.'); # TODO: hyperlink silly 
     } 
    } 
    else 
    { 
     die('no auth token'); 
    } 
} 

乾杯。

回答

1

我的猜測(根據您的評論)是,當用戶刷新時,他們再次發送POST數據,但auth_token正在更新腳本的開始,因此在$_POST(生成前一頁)將不再等於新值(在腳本的開始處生成)。

您應該看看Post/Redirect/Get以停止重新發送發佈數據。

您也可以考慮不重新生成密鑰,直到您對現有密鑰進行驗證或失效。

+0

它通常說:'哇!這似乎是你按下刷新(或後退/前進)。只需點擊這裏進行整理。「它從來沒有說'沒有授權令牌'。所以我認爲這是第二個條件。 – 2011-04-05 00:19:28

+0

@john感謝您的澄清。我假設'var_dump($ _ SESSION,$ _POST)'清楚地顯示'auth_token'成員是不同的? – alex 2011-04-05 00:24:38

+0

是的,他們是不同的 – 2011-04-05 00:34:34