使用者點擊分享連結(如商品頁、文章頁)時若未登入,被導向登入頁;登入成功後卻跳回首頁而非原本想看的頁面,體驗極差。解決方案是在攔截請求時記錄原始 URL,登入驗證通過後導回該 URL。
$_SERVER['REQUEST_URI'] + Session$_SERVER['REQUEST_URI'] 包含當前請求的完整路徑與查詢字串(不含域名)。利用 Session 暫存此值,跨頁面傳遞導向目標。
check_login.php(需在受保護頁面頂部引入)<?php
session_start();
// 若未登入,記錄當前 URL 並導向登入頁
if (!isset($_SESSION['login_ok'])) {
// 記錄完整請求 URI(含查詢字串)
$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
// 可選:友善提示後再跳轉
echo '<script>alert("請先登入以存取此頁面"); window.location.href="/login.php";</script>';
exit();
}
?>
login.php<?php
session_start();
// 假設驗證通過
$loginSuccess = verify_credentials($_POST['username'], $_POST['password']);
if ($loginSuccess) {
$_SESSION['login_ok'] = true;
$_SESSION['user_id'] = $userId;
// 取得儲存的導向目標,若無則預設首頁
$redirectUrl = $_SESSION['redirect_url'] ?? '/home.php';
// 清除已使用的導向目標,避免下次誤導
unset($_SESSION['redirect_url']);
// 方式一:HTTP Header 導向(推薦,無 JS 依賴)
header('Location: ' . $redirectUrl);
exit();
// 方式二:Meta Refresh(需顯示提示訊息時)
// echo '<meta http-equiv="refresh" content="1;url=' . $redirectUrl . '">';
// echo '登入成功,正在跳轉...';
} else {
echo '帳號或密碼錯誤';
}
?>
攻擊者可能構造惡意 redirect_url 導向釣魚網站。必須驗證 URL 屬於本站域名:
<?php
function is_safe_redirect($url) {
$host = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST);
$redirectHost = parse_url($url, PHP_URL_HOST);
return $redirectHost === $host || $redirectHost === ''; // 允許相對路徑
}
// 使用時
$redirectUrl = $_SESSION['redirect_url'] ?? '/home.php';
if (!is_safe_redirect($redirectUrl)) {
$redirectUrl = '/home.php';
}
?>
若登入表單以 AJAX 提交,回傳 JSON 讓前端處理導向:
<?php
// login.php (AJAX 版)
header('Content-Type: application/json');
$redirectUrl = $_SESSION['redirect_url'] ?? '/home.php';
unset($_SESSION['redirect_url']);
echo json_encode([
'success' => $loginSuccess,
'redirect' => $loginSuccess ? $redirectUrl : null,
'message' => $loginSuccess ? '登入成功' : '帳號密碼錯誤'
]);
?>
session_start()。REQUEST_URI 而非 PHP_SELF,後者不含查詢字串。check_login.php,否則會無限循環。「記錄原始請求 → 登入驗證 → 安全驗證導向目標 → 導向並清除記錄」四步驟構建完整的登入後返回機制。搭配開放式重導向防護與 AJAX 支援,兼顧安全性與現代前端架構需求。