You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP登录重定向异常求助:URL重复拼接错误

问题根源

错误的核心原因是使用basename()函数处理HTTP来源URL,而basename()是为文件系统路径设计的,并非URL解析工具。当$_SERVER['HTTP_REFERER']为网站根域名(如https://www.website.com)时,basename()会返回www.website.com而非预期的页面路径,拼接后就会生成../www.website.com?error=xxx的错误重定向地址,最终被解析为重复域名的URL。

解决方案

替换所有依赖basename()解析URL的逻辑,改用PHP的parse_url()函数安全提取来源页面的路径部分,同时增加异常 fallback 逻辑避免referer不存在的情况。

步骤1:添加URL路径解析辅助函数

在functions.inc.php中新增一个工具函数,用于安全获取来源页面的相对路径:

function getSafeRefererPath() {
    // 默认跳转主登录页面,可根据你的两个登录入口调整
    $defaultPath = 'login.php';
    
    if (!isset($_SERVER['HTTP_REFERER'])) {
        return $defaultPath;
    }

    $urlParts = parse_url($_SERVER['HTTP_REFERER']);
    $path = isset($urlParts['path']) ? $urlParts['path'] : '/';

    // 如果来源是根目录,返回默认登录页面
    if ($path === '/' || empty($path)) {
        return $defaultPath;
    }

    // 去掉路径开头的斜杠,转为相对路径
    return ltrim($path, '/');
}

步骤2:修改登录函数中的重定向逻辑

更新loginUser函数里的错误重定向部分:

function loginUser ($username, $password, $conn){
    $uidExists = uidExists($conn, $username, $username);
    if ($uidExists === false) {
        $result = false;
        $refererPath = getSafeRefererPath();
        // 拼接错误参数
        $errorUrl = strpos($refererPath, '?') !== false 
            ? $refererPath . "&error=wrongLogin" 
            : $refererPath . "?error=wrongLogin";
        header("location: ../".$errorUrl);
        exit();
    }

    $pwdHashed = $uidExists ['password'];
    $password= $_POST['pwd'];
    $checkPwd = password_verify($password, $pwdHashed);
    if ($checkPwd === false) {
        $refererPath = getSafeRefererPath();
        $errorUrl = strpos($refererPath, '?') !== false 
            ? $refererPath . "&error=wrongLogin" 
            : $refererPath . "?error=wrongLogin";
        header("location: ../".$errorUrl);
        exit();
    }else if ($checkPwd === true) {
        session_start();
        $_SESSION["userid"] = $uidExists ["id"];
        $_SESSION["useruid"] = $uidExists ["username"];
        $_SESSION["role"] = $uidExists["role"];
        $userID = $uidExists ["id"];
        if ($uidExists['resetFlag']!=0) {
            header("location: ../profile.php?resetFlag=1");
        }else{
            header("location: ../dashboard.php");
        }
        $result = true;
    }
    return $result;  
}

步骤3:修改Login.inc.php中的重定向逻辑

更新Login.inc.php里的空输入错误处理部分:

<?php 
session_start();
if (isset($_POST["submit"])) {
    $username = $_POST['uid'];
    $password = $_POST['pwd'];
    
    require_once 'functions.inc.php';
    require_once 'dbh.inc.php';

    if (isset($_POST['data'])){
        if (emptyInputLogin($username, $password) !== false) {
            $refererPath = getSafeRefererPath();
            $errorUrl = strpos($refererPath, '?') !== false 
                ? $refererPath . "&error=emptyinput" 
                : $refererPath . "?error=emptyinput";
            header("location: ../".$errorUrl);
            exit();
        }
        $data = $_SESSION['idata'];
        $locoData = $_SESSION['locoData'];
        uploadLogin($conn, $username, $password, $data, $locoData);
    }else{
        if (emptyInputLogin($username, $password) !== false) {
            $refererPath = getSafeRefererPath();
            $errorUrl = strpos($refererPath, '?') !== false 
                ? $refererPath . "&error=emptyinput" 
                : $refererPath . "?error=emptyinput";
            header("location: ../".$errorUrl);
            exit();
        }
        loginUser($username, $password, $conn);
    }
}else{
    header("location: ../login.php");
}
额外注意事项
  • $_SERVER['HTTP_REFERER']并非100%可靠(浏览器可能不发送或被篡改),所以设置默认跳转路径很重要。
  • 如果你的两个登录入口有明确的文件名(如login.php和admin-login.php),可以在辅助函数中根据referer的路径判断,返回对应的登录页面,确保跳转回原登录入口。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:15:56