首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 防止表單重複提交:Session Token 驗證機制完整實作

     編輯:PHP 綜合知識

使用者重複點擊提交、瀏覽器重新整理、雙擊按鈕等行為會導致表單重複提交,造成資料重複、扣款重複等嚴重問題。本文實作基於 Session Token 的一次性驗證機制,輕量、有效、易整合。

核心原理

  1. 表單頁面生成唯一 Token(時間戳或隨機字串),存入 Session 並寫入隱藏欄位;
  2. 提交時比對 $_POST['token'] 與 $_SESSION['token'];
  3. 比對成功:處理業務邏輯,立即銷毀 Session Token;
  4. 比對失敗或 Token 不存在:視為重複提交,導回表單頁或顯示提示。

完整實作代碼

<?php
session_start();

// 處理提交
if (isset($_GET['action']) && $_GET['action'] === 'save') {
    // 驗證 Token
    if (isset($_SESSION['__form_token']) &&
        isset($_POST['token']) &&
        $_SESSION['__form_token'] === $_POST['token']) {

        // Token 有效,處理業務
        print_r($_POST); // 實際處理:存資料庫、發信等

        // 關鍵:銷毀 Token,防止重複提交
        $_SESSION['__form_token'] = null;
    } else {
        // Token 無效/重複提交,導回表單
        header("Location: form.php");
    }
    exit();
}

// 生成新 Token 給表單頁
$token = $_SESSION['__form_token'] = microtime(true) . '_' . mt_rand();
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>防重複提交示範</title>
</head>
<body>
    <form action="form.php?action=save" method="post">
        <input type="hidden" name="token" value="<?php echo $token; ?>" />
        <label>用戶名: <input type="text" name="username" /></label><br>
        <label>密碼: <input type="password" name="password" /></label><br>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

關鍵細節

  • Token 複雜度:microtime(true) . '_' . mt_rand() 產生高熵值,極難碰撞;
  • 銷毀時機:務必在業務邏輯成功後銷毀,若業務失敗可保留 Token 讓使用者重試;
  • Session 依賴:需確保表單頁與處理頁同域、同 Session;
  • 靜態 HTML 頁面:若表單頁為純 HTML,可用 AJAX 先請求 /get_token.php 取得 Token 填入隱藏欄位,或改用 JS 生成並同步至 Session(需後端 API 支援)。

進階擴展

多表單並存

用陣列儲存多組 Token:$_SESSION['__form_tokens'][$form_name] = $token;

攔截器/中介層實作(框架通用)

// 概念代碼
class CsrfMiddleware {
    public function handle($request, $next) {
        if ($request->isPost()) {
            $token = $request->input('_token');
            if (!$token || $token !== $request->session()->pull('_token')) {
                return response('Invalid Token', 403);
            }
        }
        return $next($request);
    }
}

其他防重複策略對比

策略優點缺點
Session Token (本文)可靠、支援多標籤、無 JS 依賴需 Session、靜態頁需 AJAX
JS 禁用按鈕簡單、即時反饋可繞過、無法防重整
Post-Redirect-Get (PRG)防重整重複、SEO 友善不防雙擊、需配合 Token
資料庫唯一約束根治資料層重複業務邏輯複雜時難定義唯一鍵

建議採用 Token + PRG + 資料庫約束 多層防護,徹底杜絕重複提交風險。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved