應用場景
多步驟註冊/結帳流程,使用者完成最後一步後點擊「上一頁」或重新整理,可能導致重複提交、資料不一致。需在流程結束後使前序頁面失效。
核心機制:Session 狀態標記 + Cache-Control
- 入口腳本:銷毀舊 Session、建立新 Session、設定
$_SESSION['alive'] = 1
- 每個流程頁面:
header('Cache-Control: must-revalidate') 強制向伺服器驗證、檢查 alive 狀態
- 結束頁面:設定
$_SESSION['alive'] = 0 或 unset($_SESSION['alive'])
- 狀態失效時導向自訂錯誤頁
完整程式碼範例
1. entry.php (流程入口)
2. step1.php ~ stepN.php (各步驟頁面頂部)
3. final.php (最後提交處理)
4. expired.php (過期提示頁)
頁面已過期
此流程已完成或逾時
請勿重複提交。重新開始
關鍵點解析
- Cache-Control: must-revalidate:瀏覽器不得使用快取,必須向伺服器重新驗證,觸發
alive 檢查
- 私有快取:
private 避免 Proxy 快取敏感頁面
- no-store:完全禁止快存儲
- Session 銷毀時機:流程結束時才銷毀,保留其他 Session 資料 (如購物車、登入狀態)
現代替代方案
- PRG 模式:POST 後 Redirect 到 GET 頁面,重新整理不重複提交
- CSRF Token + 一次性 Token:每步驟產生唯一 Token,驗證後失效
- 前端狀態管理:SPA (Vue/React) 控制路由導航、按鈕狀態,根本不依賴瀏覽器回上頁
- Idempotency Key:API 設計冪等鍵,重複請求自動去重
安全性補充
- 敏感操作 (付費、刪除) 必須加入二次確認、OTP、風控
- Session 使用 Secure、HttpOnly、SameSite=Strict Cookie
- 流程逾時自動清理 (GC 或定時任務)