Validar acceso un solo usuario

Saludos alguien tiene un ejemplo que solo permita un sólo acceso del mismo usuario

Bueno, creo que hay varias formas de hacer esto, pero te pongo algo básico que se me ocurre y al menos te doy una idea.

Por ejemplo, se puede crear un campo en la tabla user que se llame ‘login_lock’.

Cuando ese usuario se loguea, se cambia ese campo a TRUE en la tabla, lo cual indica que el usuario está activo.

En la configuración del sitio (config/web.php) se puede usar el evento beforeRequest para controlar que no haya dos usuarios a la vez con las mismas credenciales.

'on beforeRequest' => function ($event) {
    if (!Yii::$app->user->isGuest && Yii::$app->user->identity->login_lock) {
        Yii::$app->user->logout();
        Yii::$app->response->redirect(['site/login-lock']);
    }
},

Donde esa última línea redirige a otra acción o vista donde se le dice al usuario que no puede loguearse.

Cuando el usuario haga logout, en la acción se pone el login_lock a FALSE.

Si el usuario es un manta y no hace logout, sino que cierra el navegador y puerta antes de que la sesión expire, ese login_lock se quedaría en TRUE y bloquearía cualquier login. Para evitar eso, se puede usar otro campo en la tabla, algo así como ‘last_activity’.

En la sesión de usuario, registramos ese last_activity en config/web.php

'components' => [
    'session' => [
        'class' => 'yii\web\Session',
        'cookieParams' => [
            'httpOnly' => true,
            'lifetime' => 0, // La cookie expira si el navegador se cierra
        ],
        'timeout' => 86400, // Timeout de la sesión en segundos
        'useCookies' => true,
        'name' => 'MYAPPSESSID', // el nombre de la variable de sesión
    ],
],

En el beforeRequest de config/web.php comprobaremos si el login fantasma ha excedido el tiempo de inactividad.

'on beforeRequest' => function ($event) {
    $session = Yii::$app->session;
    $lastActivity = $session->get('lastActivity');
    $maxIdleTime = 1800; // Tiempo máximo de inactividad en segundos

    if (!Yii::$app->user->isGuest && $lastActivity !== null && time() - $lastActivity > $maxIdleTime) {
        Yii::$app->user->identity->login_lock = false;
        Yii::$app->user->identity->save(false);
        Yii::$app->user->logout();
        Yii::$app->response->redirect(['site/login-lock']);
    }
},

Luego, en la acción de Login, hay que poner esa última fecha de actividad:

public function actionLogin()
{
    // ...
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
        // Fecha y hora de la última actividad del usuario
        Yii::$app->session->set('lastActivity', time());
       // ...
    }
    // ...
}

No sé si eso funcionaría, pero es una idea, como digo.

1 Like