Ads 4 You

How do I limit a user on concurrent using Yii2 and MYSQL in PHP Sessions

Email Id : phpmk888@gmail.com

------------------------Yii2-------------------------



Yii2 framework concurrent user login

Preventing login from multiple device in yii2 framework 

 This Method work Well.

 1. you do is that you add an extra column to your users table, name it 'conc_login' or preferably text because it might be difficult to predict the size of data we are expecting.

 2. when the user logs in, check if the logins column is empty, if it is empty, create a json that contains the session_id, time of login using the time() function.

 3. If the logins column is not empty or the count of the column when decoded is greater than zero, then you check if the count is greater than login limit , if the number of logins is not yet greater than the login limit, then append the new session to the logins column in the database table

 4. If the login limit is reached then check through the logins and check for the one with expired time, for example, a user that is not active of 300secnds is assumed to be logged out, then you delete the session that has expired from the table

 5. In any request that is been made by a logged user you check if the session key still exists in the login column of the database ($logins[‘session_key’]), and if it is not found then log the user out immediately to avoid escalation of right and if otherwise then update the $login[‘time’] to the new time(). You can implement this code.

 1. Login Form Model Add this function for concurrent user validation
 


$get_limit = Setting::findOne(['name' => 'login_limit']);
$login_limit = 3; //$get_limit->value;

$active_sess = User::findOne($getUser->id);

if ($active_sess->conc_login == '' or count(json_decode($active_sess->conc_login)) == 0) {
    $login_json = json_encode([
        [Yii::$app->session->getId() => Yii::$app->session->getId(), 'session_key' => Yii::$app->session->getId(), 'time' => time()]
    ]);
    $active_sess->conc_login = $login_json;
    $active_sess->save();
} else if (count(json_decode($active_sess->conc_login)) > 0 and count(json_decode($active_sess->conc_login)) < $login_limit) {

    $login_json = json_decode($active_sess->conc_login);
    $login_json[] = [Yii::$app->session->getId() => Yii::$app->session->getId(), 'session_key' => Yii::$app->session->getId(), 'time' => time()];
    $login_json = json_encode($login_json);
    //print_r($login_json); exit;                
    $active_sess->conc_login = $login_json;
    $active_sess->save();
} else if (count(json_decode($active_sess->conc_login)) >= $login_limit) {

    $logins = json_decode($active_sess->conc_login);

    
    foreach ($logins as $key => $login) {
        if ($login->time < time() - 120) {
            //this checks if the iterated login is greater than the current time -120seconds and if found to be true then the user is inactive
            //then set this current login to null by using the below statement
            //$logins[$key] = null; // or unset($logins[$key]) either should work;
            unset($logins[$key]);
        }
    }
 
    //after iteration we check if the count of logins is still greater than the limit
    if (count($logins) >= $login_limit) {
        //then return a login error that maximum logins reached
        //echo 'you are not allowed to login as you have breeched the maximum session limit.';
        //exit;
        $login_json = json_encode($logins);
        $active_sess->conc_login = $login_json;
        $active_sess->save();

        $this->addError($attribute, 'you are not allowed to login as you have breeched the maximum session limit.');

    } else {
        //then login is successsfull

        $login_json = [];
        foreach ($logins as $key => $val) {
            $login_json[] = [$val->session_key => $val->session_key, 'session_key' => $val->session_key, 'time' => $val->time];
        }
        $login_json[] = [Yii::$app->session->getId() => Yii::$app->session->getId(), 'session_key' => Yii::$app->session->getId(), 'time' => time()];
        $login_json = json_encode($login_json);

        $active_sess->conc_login = $login_json;
        $active_sess->save();
    }

    //update the logins column to equal to json_encode($logins);
}


2. User side update session every 60seconds : SiteController


 


public function actionUserSessionUpdate() {
    $session = Yii::$app->session;
    $userid = $session->get('userid');
    $username = $session->get('username');
    $data = array('session_id' => Yii::$app->session->getId());
    $isUserLogin = (!empty($userid) && !empty($username)) ? 'true' : 'false';
    if ($isUserLogin == 'false') {
        echo 'gotologin'; exit;
        //return $this->redirect(['/login']);
    } else {
        //Login user
       
        $active_sess = Clientmanagement::findOne($userid);
        $loginjson = json_decode($active_sess->conc_login);
       
        $login_json = [];
        foreach ($loginjson as $key => $val) {
            if ($val->session_key == Yii::$app->session->getId()) {
                $login_json[] = [$val->session_key => $val->session_key, 'session_key' => $val->session_key, 'time' => time()];
            } else {
                $login_json[] = [$val->session_key => $val->session_key, 'session_key' => $val->session_key, 'time' => $val->time];
            }
        }

        
        $login_json = json_encode($login_json);
        $active_sess->conc_login = $login_json;
        $active_sess->save();
    }
    exit;
}

3. Client ajax 


 

get('userid'))) {

    $usersession_url = Yii::$app->urlManager->createAbsoluteUrl(["/site/user-session-update"]);

    $scriptb = <<< JS
    $(document).ready(function () {
            //Wait 1 Minutes
       setInterval(function(){ 
                $.ajax({
               type:"post",
               data:'id=session',
               url:"$usersession_url",
               success:function(data){

               }
           });
           }, 60000);  
    });
JS;
    $this->registerJs($scriptb);
}
?>

3. UserController Logout
 


public function actionLogout() {
    $session = Yii::$app->session;
    $userid = $session->get('userid');
  
    //concurrent active user session removed
    $active_sess = Clientmanagement::findOne($userid);
    $loginjson = json_decode($active_sess->conc_login);
    foreach ($loginjson as $key => $login) {
        if ($login->session_key == Yii::$app->session->getId()) {
            unset($loginjson[$key]);
        }
    }
    $login_json = json_encode($loginjson);   
      
    $active_sess->conc_login = $login_json;
    $active_sess->save();
        
    $session->destroy();
    return $this->redirect(['/login']);
}

Comments


  1. Nice information. Thanks for sharing content and such nice information for me. I hope you will share some more content about. Please keep sharing!
    Dedicated Yii Framework Developers in India

    ReplyDelete

Post a Comment