如何为单个PHP页面(OTP.php)实现多密码验证保护?
Alright, let's integrate four distinct verification layers between your process.php and OTP.php while keeping your existing flow intact. The core idea is to use session storage to persist transfer data across steps, enforce sequential verification, and only allow access to OTP.php once all four checks pass.
1. Modify process.php to Initiate the Verification Flow
Instead of redirecting directly to OTP.php, we'll save the transfer details to the session and send users to the first verification step:
// process.php - After handling the initial transfer form data session_start(); // Store sensitive transfer data (encrypt this if needed for extra security) $_SESSION['transfer_context'] = [ 'amount' => $_POST['amount'], 'recipient_account' => $_POST['recipient'], 'sender_account' => $_SESSION['user_account'] // Assume you have user session data ]; // Initialize verification step tracker $_SESSION['current_verify_step'] = 1; // Redirect to first verification page header("Location: " . WEB_ROOT . "view/VerifyStep1.php"); exit;
2. Create Four Distinct Verification Pages
Each page will handle one unique verification type, validate user input, and progress to the next step only if successful. We'll enforce step order to prevent skipping ahead.
Step 1: Transaction Password Verification
Create VerifyStep1.php for a user-defined 6-digit transaction password:
<?php session_start(); // Block direct access if session is invalid or step is wrong if (!isset($_SESSION['transfer_context']) || $_SESSION['current_verify_step'] != 1) { header("Location: " . WEB_ROOT . "view/Fundstransfer.php"); exit; } $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_pwd = $_POST['transaction_pwd']; // Fetch hashed transaction password from your database $stored_pwd_hash = get_user_transaction_pwd($_SESSION['user_id']); // Replace with your DB call if (password_verify($input_pwd, $stored_pwd_hash)) { // Move to next step $_SESSION['current_verify_step'] = 2; header("Location: " . WEB_ROOT . "view/VerifyStep2.php"); exit; } else { $error = 'Incorrect transaction password. Please try again.'; } } ?> <!DOCTYPE html> <html> <head> <title>Verification Step 1/4: Transaction Password</title> </head> <body> <h3>Transfer Security Check - Step 1</h3> <?php if ($error): ?> <p style="color: #dc3545;"><?php echo $error; ?></p> <?php endif; ?> <form method="post"> <label>Enter your 6-digit transaction password:</label> <input type="password" name="transaction_pwd" maxlength="6" required> <button type="submit">Next Step</button> </form> </body> </html>
Step 2: Security Question Verification
Create VerifyStep2.php for a pre-configured security question (e.g., "What was your first pet's name?"):
<?php session_start(); if (!isset($_SESSION['transfer_context']) || $_SESSION['current_verify_step'] != 2) { header("Location: " . WEB_ROOT . "view/Fundstransfer.php"); exit; } $error = ''; // Fetch user's security question and hashed answer from DB [$question, $stored_answer_hash] = get_user_security_question($_SESSION['user_id']); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_answer = $_POST['security_answer']; if (password_verify(strtolower($input_answer), $stored_answer_hash)) { $_SESSION['current_verify_step'] = 3; header("Location: " . WEB_ROOT . "view/VerifyStep3.php"); exit; } else { $error = 'Incorrect answer to security question.'; } } ?> <!DOCTYPE html> <html> <head> <title>Verification Step 2/4: Security Question</title> </head> <body> <h3>Transfer Security Check - Step 2</h3> <?php if ($error): ?> <p style="color: #dc3545;"><?php echo $error; ?></p> <?php endif; ?> <form method="post"> <label><?php echo $question; ?></label> <input type="text" name="security_answer" required> <button type="submit">Next Step</button> </form> </body> </html>
Step 3: Backup Phone SMS Verification
Create VerifyStep3.php for a one-time code sent to the user's backup phone number:
<?php session_start(); if (!isset($_SESSION['transfer_context']) || $_SESSION['current_verify_step'] != 3) { header("Location: " . WEB_ROOT . "view/Fundstransfer.php"); exit; } $error = ''; // Generate and send SMS code on first load if ($_SERVER['REQUEST_METHOD'] === 'GET' && !isset($_SESSION['backup_sms_code'])) { $sms_code = rand(100000, 999999); $_SESSION['backup_sms_code'] = $sms_code; // Send code via your SMS API (replace with your implementation) send_sms($_SESSION['user_backup_phone'], "Your transfer verification code is: $sms_code"); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_code = $_POST['sms_code']; if ($input_code === $_SESSION['backup_sms_code']) { unset($_SESSION['backup_sms_code']); // Clean up temporary code $_SESSION['current_verify_step'] = 4; header("Location: " . WEB_ROOT . "view/VerifyStep4.php"); exit; } else { $error = 'Invalid SMS verification code.'; } } ?> <!DOCTYPE html> <html> <head> <title>Verification Step 3/4: Backup Phone SMS</title> </head> <body> <h3>Transfer Security Check - Step 3</h3> <?php if ($error): ?> <p style="color: #dc3545;"><?php echo $error; ?></p> <?php endif; ?> <form method="post"> <label>Enter the 6-digit code sent to your backup phone:</label> <input type="text" name="sms_code" maxlength="6" required> <button type="submit">Next Step</button> </form> </body> </html>
Step 4: Hardware Token Verification (e.g., Google Authenticator)
Create VerifyStep4.php for a time-based one-time code from a hardware token or authenticator app:
<?php session_start(); if (!isset($_SESSION['transfer_context']) || $_SESSION['current_verify_step'] != 4) { header("Location: " . WEB_ROOT . "view/Fundstransfer.php"); exit; } $error = ''; // Fetch user's Google Authenticator secret from DB $ga_secret = get_user_ga_secret($_SESSION['user_id']); // Use a GA library (e.g., PHPGangsta/GoogleAuthenticator) require_once 'GoogleAuthenticator.php'; $ga = new PHPGangsta_GoogleAuthenticator(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_code = $_POST['ga_code']; // Allow 2-minute time window for code validity if ($ga->verifyCode($ga_secret, $input_code, 2)) { // All steps completed - mark as verified $_SESSION['verification_completed'] = true; header("Location: " . WEB_ROOT . "view/OTP.php"); exit; } else { $error = 'Invalid authenticator code.'; } } ?> <!DOCTYPE html> <html> <head> <title>Verification Step 4/4: Authenticator Token</title> </head> <body> <h3>Transfer Security Check - Step 4</h3> <?php if ($error): ?> <p style="color: #dc3545;"><?php echo $error; ?></p> <?php endif; ?> <form method="post"> <label>Enter code from your authenticator app:</label> <input type="text" name="ga_code" maxlength="6" required> <button type="submit">Complete Verification</button> </form> </body> </html>
3. Secure OTP.php to Enforce Verification
Modify OTP.php to only allow access if all four steps are completed:
<?php session_start(); // Block access if verification isn't done or transfer data is missing if (!isset($_SESSION['transfer_context']) || !isset($_SESSION['verification_completed'])) { header("Location: " . WEB_ROOT . "view/Fundstransfer.php"); exit; } // Your existing OTP generation and display logic here... ?>
Critical Security Notes
- Encrypt Session Data: Sensitive transfer details in the session should be encrypted to prevent exposure if the session is hijacked.
- Rate Limiting: Add limits on failed attempts per step (e.g., 3 tries before locking the user out for 15 minutes) to block brute-force attacks.
- Session Cleanup: After the transfer completes (success or failure), clear the
transfer_context,current_verify_step, andverification_completedsession variables. - HTTPS: Ensure all pages use HTTPS to prevent data interception during form submissions.
内容的提问来源于stack exchange,提问作者TopKlass digitalstudios

