【问题标题】:php session variable randomly changesphp会话变量随机变化
【发布时间】:2014-05-18 18:22:23
【问题描述】:

我有一个拥有会员系统的网站。当用户登录时,我从数据库验证用户名/密码并启动一个会话,$_SESSION['userid'] 包含他们的 id(我还没有使用 cookie 实现任何东西)

我有一个问题,系统在大多数情况下都可以正常工作,但有些用户报告说他们最终发现自己登录到了其他一些随机用户帐户。这可能意味着 $_SESSION['userid'] 毫无理由地更改为其他内容,我很确定我没有做任何更改。

任何想法为什么会发生这种情况?

编辑:我在做什么的总结

此方法启动会话

function startSession($id){
$_SESSION['logged_in'] = 1;
$_SESSION['userid'] = $id;
}

此方法检查登录

function isLoggedIn(){ 
    return isset($_SESSION['logged_in']) && isset($_SESSION['userid']) && $_SESSION['userid']!=" " && $_SESSION['logged_in']==1;
}

这是注销方法

function logout(){
    $_SESSION['logged_in'] = 0;
    $_SESSION['userid'] = 0;
    unset($_SESSION['logged_in']);
    unset($_SESSION['userid']);
    session_destroy();
    if (!isLoggedIn()){ return "S3"; }
    else { return "E3"; }
}

这就是我检查用户是否在大多数地方登录的方式

if (isLoggedIn()){ $profileid = $_SESSION['userid']; }

这是登录函数,这里是我调用startSession的地方

function login($username, $password){
    $pdo = newPDO();
    $username = sanitize_string($username);
    $password = sha1(sanitize_string($password));
    $query = $pdo->prepare("SELECT id FROM ".TABLE_PROFILE." WHERE nick=:nick AND pass=:pass LIMIT 1");
    $query->execute(array(':nick'=>$username, ':pass'=>$password));
    $result = $query->fetch(PDO::FETCH_ASSOC);
    if (count($result['id']) == 1){ 
        startSession($result['id']);
        loginExecution();
        return "S1";
    }
    else{ return "E1"; }
}

【问题讨论】:

  • 您需要为您正在使用的所有页面发布代码。可能的原因太多了。
  • @Fred-ii- 不同文件中有数千行代码。我只需要对可能出错的地方提出意见^^
  • 问题不在SESSION上,是你的登录脚本的问题。如果您想获得正确的解决方案,请发布脚本
  • 哼,奇怪。也许一个仍然活跃的会话 id 被分配给了另一个用户。当另一个用户获得相同的会话 ID 时,他们将控制该帐户。但如果没有手动设置会话 ID,则不太可能发生这种情况。
  • “我”太难说了。通常会话是从$_POST 变量分配的,例如$user=$_POST['user']; $_SESSION['user'] = $user; 类型的事物。如果除此之外还有任何其他变化,或者您已将其分配给列/行,那么这可能是一个因素。

标签: php session web session-variables session-state


【解决方案1】:

问题出在你的登录功能上

您的脚本不会检查用户名和密码是否有任何数据,如果用户名和密码为空或不正确,您的客户端将从数据库中获取第一个可用的 ID。

function login($username, $password){
    $pdo = newPDO();
    $username = sanitize_string($username);
    $password = sanitize_string($password);

    // Check data for existing
    if (empty($username)) throw new Exeption('Empty username');
    if (empty($password)) throw new Exeption('Empty password');

    $password = sha1($password);

    $query = $pdo->prepare("SELECT id FROM ".TABLE_PROFILE." WHERE nick=:nick AND pass=:pass LIMIT 1");
    $query->execute(array(':nick'=>$username, ':pass'=>$password));
    $result = $query->fetch(PDO::FETCH_ASSOC);
    if (count($result['id']) == 1){ 
        startSession($result['id']);
        loginExecution();
        return "S1";
    }
    else{ return "E1"; }
}

附:在 SQL 查询之前始终检查传入数据

【讨论】:

  • 我从另一个由 ajax 调用的脚本调用登录函数,这就是我检查用户名和密码是否设置的地方。这是代码: if ( isset($_POST['username']) && isset($_POST['password'])){ $logged = login($_POST['username'] , $_POST['password ']);回声 getMessage($logged); } 其他{ 回声 getMessage("E5"); }
  • Javascript 验证对于授权表单来说是一个非常糟糕的主意,因为如果客户端在浏览器中禁用了 javascript,验证将不起作用
  • 在我看来 TS 肯定必须测试输入 args,但无论如何如果 args 为空,查询将返回一个空集,我想该表不包含具有空数据的行。
  • isset 函数返回真,如果登录是“空格”。您必须使用空函数进行检查
  • 真,空间的东西会在isset()处返回真。但是这些并不能解释令人兴奋的事实,即会话 id 会神奇地改变:D 对此有什么想法吗?
【解决方案2】:

实际上,我能想到的唯一一件事就是将 $_SESSION['userid'] 设置为另一个成员 ID。假设这是您用来检查要显示的成员信息的内容。如果未设置 $_SESSION['userid'] 变量可能会导致错误地设置 $_SESSION['userid'] ,您是否正在做某事?即如果他们的 php 会话被重置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2013-05-09
    • 2014-06-22
    • 2014-11-20
    • 2012-08-03
    • 2013-05-01
    相关资源
    最近更新 更多