【问题标题】:Can't Delete cookie in user class with php无法使用 php 删除用户类中的 cookie
【发布时间】:2009-11-08 12:09:53
【问题描述】:

我觉得我的问题有点奇怪,我写了一个小类来登录/注销用户,整个系统基于 MVC 模式,我的库是自定义和自己编写的, 但问题是:当我在没有 $remember 标志的情况下登录用户时,没有问题,会话很容易设置和取消设置。但是当我激活 $remember 并创建一个 cookie 时,我的注销功能不起作用,它会删除会话但不会删除 cookie,因此 cookie 会保留在浏览器中的完整数据,并且每当我重新加载页面时,我的班级都会让我登录再次因为有一个包含完整身份验证详细信息的 cookie,问题出在 cookie 上,我无法发送其他标头,例如 Location: blah blah from $this->logout;我尝试了不同的方法来取消设置 cookie,但没有运气; 这是课程:

<?php
/**
 * Pars----
 * Classified --- Application
 *
 * @author Sallar Kaboli (me@sallar.ir)
 * @copyright Copyright (C) 2009 - 2010 -----CO (dev@------.us)
 * @package Pars---
 * @version 1.0
 */

class ParsUser {

    public $userID = false;

    private $_p = null;
    public $userData = null;

    public function __construct() {
        $this->_p = ParsRegistry::getInstance();
        if( $this->_p->sess->isVarSet('parsUser') ) {
            $this->loadUser($this->_p->sess->getVar('parsUser'));
        }

        if( isset($_COOKIE['parsUser']) and !$this->isLoggedIn() ) {
            $userFromCookie = unserialize(base64_decode($_COOKIE['parsUser']));
            $this->checkLogin($userFromCookie['username'], $userFromCookie['password'], true, false);
        }
    }

    public function checkLogin($username, $password, $remember = true, $hash = true) {

        if(!empty($username) and !empty($password)) {

            $password = $hash ? $this->_p->valid->hash($password) : $password;
            $qData = array('user' => $username, 'pass' => $password);
            $query = 'SELECT * FROM people WHERE `username` = :user AND `password` = :pass';

            $user = $this->_p->db->getRow($query, $qData);

            if(is_object($user) AND !empty($user->id)) {

                $this->userID = $user->id;
                $this->userData = $user;

                if( $hash ) {
                    $this->_p->db->execute('UPDATE people SET `last_login` = ? WHERE `id` = ?', array( time(), $this->userID ));
                }

                $this->loginTheUser($remember);
                return true;

            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    }

    private function loginTheUser($remember = true) {
        $this->_p->sess->setVar('parsUser', $this->userID);

        if( $remember ){
            $rememberPeriod = $this->_p->conf->c['cookie_remember_period'];
            $cookie = array(
                      'username' => $this->userData->username,
                      'password' => $this->userData->password
                      );

            $cookie = base64_encode(serialize($cookie));
            setcookie('parsUser', $cookie, time() + $rememberPeriod/*, '/', $_SERVER['HTTP_HOST']*/);
        }
        return false;
    }

    private function loadUser($userID){

        $user = $this->_p->db->getRow('SELECT * FROM people WHERE `id` = ?', $userID);

        if( is_object($user) and ( $user->id == $userID ) ){

            $this->userID = $user->id;
            $this->userData = $user;
            $this->_p->sess->setVar('parsUser', $this->userID);

            return true;
        }
        else return false;

    }

    public function logout($redirectTo = false) {
        setcookie('parsUser', '', mktime(12,0,0,1, 1, 1990));
        unset($_COOKIE['parsUser']);
        $this->_p->sess->sessionDrop();
        $this->userData = null;
        $this->userID = false;

        if ( !empty($redirectTo) ){
               $this->_p->core->redirect($redirectTo);
               exit;
            }
    }

    public function isLoggedIn() {
        //return ( empty($this->userID) OR !$this->userID ) ? false : true;

        if( $this->userID > 0 and $this->userID != false and !empty($this->userID) )
            return true;
        else return false;
    }

    public function checkAccess($level) {
        if($level == 0) {
            return true;
        }
        elseif($this->isLoggedIn()) {
            if( $this->userData->level <= $level ) {
                return true;
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    }

    public function getUserData() {

        $args = func_get_args();

        if( empty($this->userID) )
           throw new Exception('User is not loaded.');

        if( is_array($args) and count($args) > 0){
            foreach( $args as $arg ){
                if( !isset($this->userData->$arg) )
                    throw new Exception('Unknown property: <b>' . $property . '</b>');
                else
                    $props[$arg] = $this->userData->$arg;
            }

            if( count($args) == 1 )
                return $props[$args[0]];
            else
                return $props;
        }
        else{
            $props = $this->userData;
            unset($props->password);
            return $props;
        }

    }


}

对不起我的英语。

【问题讨论】:

  • 您是否查看了服务器在响应中发送的内容? HTTP 标头中有对应的Set-Cookie 还是缺失?
  • 不,我没有,我要去看看。 tnx

标签: php class session cookies


【解决方案1】:

尝试在这两种情况下设置 $path(创建、删除 cookie)

【讨论】:

  • 谢谢,这工作。我是多么愚蠢。登录和注销 url 完全不同,例如 site.com/user/loginsite.com/user/logout ,所以当我设置没有路径 '/' 的 cookie 时,服务器仅为 /login/ 设置 cookie,我无法将其从 /logout 中删除。 "默认值是设置 cookie 的当前目录。"
【解决方案2】:

您可以使用无效数据设置 cookie:

setcookie('parsUser', 'trash', time() - 3600);

如果这不会删除 cookie,它至少应该创建一个无效的登录令牌。

我还建议不要在 cookie 中对用户名和密码进行 base64 编码。对于有经验的攻击者来说,这几乎是纯文本。您可以使用 mcrypt 轻松地将强加密集成到您的应用程序中:

http://us2.php.net/mcrypt

如果这不是一个选项,您可以使用仅 php 实现的 xor 加密和强密钥。互联网上还有仅 php 的河豚和 Rijndael 实现。如果可以,我会提供链接,但我目前的声誉不允许我添加多个超链接。

【讨论】:

  • 关于cookie,我来看看。我同意base64。这只是为了测试。它不是最后的课程。谢谢。
  • 我刚刚检查过了,我也无法更改 cookie 的值。 @Gumbo:这是服务器响应,当我从控制器调用注销方法时:如您所见,服务器尝试更改值,但 cookie 没有更改。 img3.tinypic.info/files/mo5mjgecac7ss2a18o0f.jpg 尝试在 setcookie 之前放置一个 echo 以检查它是否运行,它确实运行,以及服务器响应。但是...
  • Tnx Luu,我设法用 mcrypt 实现了 Rijndael,非常完美。再次感谢。
【解决方案3】:

抱歉我的奇怪问题,但为什么你在历史记录中设置一个 cookie(所以它被删除)然后取消设置一个不再存在的 cookie?

如果您查看图像的输出,嗯,看起来很奇怪... 您的服务器的系统时间是多少? 因为它说 cookie 将在 1990 年到期。如果仍然有效的话,看起来你的计算机/服务器已经落后了:P

顺便说一句,可能你不能编辑数据,因为你需要先解码base64加密(因为在你设置的代码中,你使用了base64函数)

【讨论】:

  • 那是因为历史上的setcookie()不起作用,我试图取消它,但我也没起作用。
猜你喜欢
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2012-12-21
  • 1970-01-01
相关资源
最近更新 更多