How to guarantee unique access to each user?

Asked

Viewed 579 times

7

How can I ensure that when a user is online, they no longer allow connections with the user login and password, taking into account that if the session expires, you can again allow connections from login and password?

I’ve been reading Know if user is connected PHP and I was left with that doubt.

NOTE: No use of cookies

  • 3

    I want to see how to save the session without a cookie (you can do it, but you have to pass the ID through the URL). I find it much easier to let you always log in, but every time you log in, kill the previous session. Much simpler, without danger of locking itself out, and without the risk of simultaneous use. Now, the strong impression I have is that this may even have some legitimate application, but it probably serves to cover some other application failure.

  • 1

    No cookie, I think, just like this: http://stackoverflow.com/a/3643602

  • @Bacco liked the idea you don’t want to formulate an answer?

  • 1

    @Jorgeb. To tell you the truth, if I was going to answer, I would prefer to use that other one, first for the restriction of cookies, which I don’t think has much to do with the problem, and despite minor differences in the formulation, I think in the end is the same question. Actually I wouldn’t even have much to add besides the comment I made, it would be basically that. Logou, invalidates the previous login, only. For example, associating the session ID to the user ID. If not.

1 answer

6


Through a Handler of custom sessions you can do this because you can perform a different routine at each stage of the session: opening, closing, reading, recording, removing and garbaging.

To create a custom session handler use the function session_set_save_handler()

Handler below, based on Mysqli, will use a simple SQL framework:

CREATE TABLE `session_data` (
  `id` varchar(32) NOT NULL,
  `data` text,
  `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8_unicode_ci;

The Handler:

class SessionSaveHandler {

    protected $link;
    protected $table;

    protected $sessionName = 'session';
    protected $maxLifeTime = 3600;

    public function __construct( $user = null, $pass = null, $host = null, $db = null, $table = null, $sessionName = null ) {

        $this -> link = mysqli_connect( $host, $user, $pass, $db );

        if( ! $this -> link ) {
            throw new Exception( 'Could not connect to the database!' );
        }

        mysqli_select_db( $this -> link, $db );

        session_set_save_handler(

            array( $this, 'open' ),
            array( $this, 'close' ),
            array( $this, 'read' ),
            array( $this, 'write' ),
            array( $this, 'destroy' ),
            array( $this, 'gc' )
        );

        $this -> table = $table;

        session_name( $this -> sessionName );

        session_start();
    }

    public function open( $savePath, $sessionName ) {

        $this -> sessionName = $sessionName;

        return TRUE;
    }

    public function close() {
        return true;
    }

    public function read( $id ) {

        $query = sprintf(

            'SELECT `data` FROM %s WHERE `id` = ? AND UNIX_TIMESTAMP( `last_updated` ) + %d > UNIX_TIMESTAMP( NOW() )',

            $this -> table, $this -> maxLifeTime
        );

        $stmt = mysqli_prepare( $this -> link, $query );

        mysqli_stmt_bind_param( $stmt, 's', $id );

        if( mysqli_execute( $stmt ) ) {

            mysqli_stmt_bind_result( $stmt, $retval );

            mysqli_stmt_fetch( $stmt );

            if( ! empty( $retval ) ) return $retval;
        }

        return '';
    }

    public function write( $id, $data ) {

        $query = sprintf(

            'INSERT INTO %s (id, data) VALUES (?, ?) ON DUPLICATE KEY UPDATE data = ?, last_updated=NULL',

            $this -> table
        );

        $stmt = mysqli_prepare( $this -> link, $query );

        mysqli_stmt_bind_param( $stmt, 'sss', $id, $data, $data );

        return mysqli_execute( $stmt );
    }

    public function destroy( $id ) {

        $query = sprintf( 'DELETE FROM %s WHERE id = ?', $this -> table );

        $stmt = mysqli_prepare( $this -> link, $query );

        mysqli_stmt_bind_param( $stmt, 's', $id );

        return mysqli_execute( $stmt );
    }

    public function gc( $maxlifetime ) {

        $query = sprintf(
            'DELETE FROM %s WHERE UNIX_TIMESTAMP( last_updated ) + %d <= UNIX_TIMESTAMP( NOW() )',
            $this -> table, $this -> maxLifeTime
        );

        mysqli_query( $this -> link, $query );

        return;
    }
}

And its use:

require_once 'handler.php';

new SessionSaveHandler( 'root', '7v4h6q7t', 'localhost', 'session', 'session_data' );

$_SESSION['name'] = 'Bruno Augusto'; // write
$_SESSION['age']  = 26; // write

var_dump( $_SESSION['name'] ); // read

unset( $_SESSION['age'] );

var_dump( $_SESSION ); // proof

That one Handler generic allows session data to be recorded, read and manipulated in a database. Point!

Now, what do you say really the scope of the topic is precisely to customize the behavior. For example, just add a new column to the table to make the condition according to the reference link that raised the doubt and modify the queries of the methods Sessionhandler::write() and Sessionhandler::read() (for safety) to take account of it.

This way when creating the session variable, thus triggering the method Sessionhandler::write() the index shall be created only if the condition of existence is satisfied.

And thanks to her, when checking if the session index exists to free up access to a given page, even having been created, everything is solved practically by itself.

  • I did that and it’s giving me NULL on var_dump( $_SESSION );

  • Assuming you have created the database, defined the user and passwords different from the randomly generated ones I used and configured correctly, you will need to be a little more specific because when I wrote it I tested and worked perfectly.

  • I decided, I forgot to put PRIMARY KEY (id). Then I delete the comments.

  • 2

    Don’t do this. If suddenly someone else has the same problem as you, you will already have an answer.

  • There’s something not working right, with every menu I go header('Location: index.php?menu=1'); logout is done on the page, but the entry is in the BD.

  • And every logout I do doesn’t erase the bank log.

  • I would suggest you create a new topic with what you’ve done, more or less, so we can look at it from another angle. But in the meantime, try calling session_write_close() before header(), forcing the session mechanism to record data.

  • http://answall.com/questions/42609/o-meu-sessionhandler-n%C3%A3o-me-permite-iniciar-a-sess%C3%A3o

  • the problem is that it does not erase even the record on time, should be only x in x time (think).

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.