使用数据库会话登录?

使用数据库会话登录?

问题描述:

I have been trying to get my login script to work with database managed sessions.

This is my database session class:

class SessionManager {
    var $life_time;

    function SessionManager() {
        // Read the maxlifetime setting from PHP
        $this->life_time = 600; //10 minutes

        // Register this object as the session handler
        session_set_save_handler(array( &$this, "open" ), 
                                 array( &$this, "close" ),
                                 array( &$this, "read" ),
                                 array( &$this, "write"),
                                 array( &$this, "destroy"),
                                 array( &$this, "gc" )
                                 );
   }

    function open( $save_path, $session_name ) {
        global $sess_save_path;

        $sess_save_path = $save_path;
        // Don't need to do anything. Just return TRUE.
        return true;
    }

    function close() {
        return true;
    }

    function read( $id ) {
        // Set empty result
        $data = '';

        // Fetch session data from the selected database
        $time = time();

        $newid = mysql_real_escape_string($id);
        $sql = "SELECT 
                    `session_data` 
                FROM 
                    `sessions` 
                WHERE 
                    `session_id` = '$newid' 
                AND 
                    `session_expire` > $time";

        $rs = mysql_query($sql);                           
        $a = mysql_num_rows($rs);

        if($a > 0) {
            $row = mysql_fetch_assoc($rs);
            $data = $row['session_data'];
        }

        return $data;
    }

    function write($id, $data) {
            // Build query                
            $time = time() + $this->life_time;

            $newid = mysql_real_escape_string($id);
            $newdata = mysql_real_escape_string($data);

            $sql = "INSERT INTO `sessions` (`session_id`, `session_data`, 
                                              `session_expire`, `session_agent`, 
                                              `session_ip`) 
                                            VALUES
                                            (\"".$id."\", \"".$data."\",
                                             \"".time()."\",\"".$_SERVER['HTTP_USER_AGENT']."\",
                                             \"".$_SERVER['REMOTE_ADDR']."\")
                                            ON DUPLICATE KEY UPDATE 
                                            `session_id` = \"".$id."\",
                                            `session_data` = \"".$data."\",
                                            `session_expire` = \"".time()."\"";

            $rs = mysql_query($sql) or die(mysql_error());

            return true;
    }

    function destroy($id) {
        // Build query
        $id = mysql_real_escape_string($id);
        $sql = "DELETE FROM `sessions` WHERE `session_id`='$id'";
        mysql_query($sql);

        return true;
    }

    function gc(){
        // Garbage Collection
        // Build DELETE query.  Delete all records who have passed the expiration time
        $sql = 'DELETE FROM `sessions` WHERE `session_expire` < UNIX_TIMESTAMP();';
        mysql_query($sql);

        // Always return TRUE
        return true;
    }
}

This is a part of my login class:

function process_login(){
        global $mysql_prefix;

        $email = mysql_real_escape_string($_POST['email']);
        $check = mysql_query("SELECT password,salt,id FROM ".$mysql_prefix."users WHERE email='$email'");

        if(mysql_num_rows($check) > 0){
            $info = mysql_fetch_assoc($check);
            $private_key = $this->get_secret_key();
            $password = hash('sha256', $info['salt'] . hash('sha256', $private_key.$_POST['password']));

            if($password == $info['password']){
                $_SESSION[$this->user_session]['id'] = $info['id'];

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

I have required the session class in my global.php file and called the class (or whatever it is called), but how do I actually go about and use this new database session system with my current login class?

I tried to use $ManageSessions->write(id, data) like this:

function process_login(){
        global $mysql_prefix;

        $email = mysql_real_escape_string($_POST['email']);
        $check = mysql_query("SELECT password,salt,id FROM ".$mysql_prefix."users WHERE email='$email'");

        if(mysql_num_rows($check) > 0){
            $info = mysql_fetch_assoc($check);
            $private_key = $this->get_secret_key();
            $password = hash('sha256', $info['salt'] . hash('sha256', $private_key.$_POST['password']));

            if($password == $info['password']){
                $SessionManager->write(session_id(),$info['id']);

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

But it does not seem to work, and the data is overwritten the second the page is updated.

I must be missing something obvious, or just coding something wrong.

(I am aware of the security flaws in the script and I am in the process of redesigning it, so please don't say anything about security or like. Thanks :))

The class above substitutes php's session system with the one in the class. When you make a new instance of the class, its constructor (the function SessionManager() {) is called, setting the functions in the class to run instead of php's defaults. So now when you write something to the $_SESSION, it uses SessionManager's write functions, which adds it to the database.

So basically, just initialize that class on every page, and then use your sessions like you normally would. They'll all just show up in the database.