Ryan Arief
Ryan Arief

Reputation: 1045

Yii2 Logout Specific User

How can I tell yii2 to logged out specific user who has login to system?

Let say, there is 2 user is logged in on system, userA and userB.

How can I specified logged out userB?

What I know is userB has to trigger this command to logout.

Yii::$app->user->logout();
return $this->goHome();

But maybe we can use some command like Yii::$app->user->logout('userB');?

Or is it has some other way?

Upvotes: 11

Views: 10487

Answers (3)

Lionel Bautista
Lionel Bautista

Reputation: 31

If you are still looking for a solution to this, just change the auth_key of the user that you want to logout. This auth_key is used by the system to remember if a user is logged in, thus changing this will invalidate any session that uses this key.

Example to logout a user with id=100

$user = User::findOne(100);
$user->generateAuthKey(); //a function in User (Identity) class that generates the auth_key
$user->save();

Upvotes: 3

Alex
Alex

Reputation: 553

If you are using a model User for storing auth credentials, you can simply change the value of 'id' (and also a key '100') to some other integer value, to make user fail auth on his next request.

In other words, you must change all '100', for example to '200' in this code:

file: /models/User.php

private static $users = [
    '100' => [
        'id' => '100',
        'username' => 'admin',
        'password' => 'password_for_admin',
        'authKey' => '43e02a0f0e5f6a7907b2f2c69a765be7',
        'accessToken' => '7b2f2c69a765be743e02a0f0e5f6a790',
    ],
];

Upvotes: 0

SilverFire
SilverFire

Reputation: 1592

Well, the problem is about how to kill all sessions of the user.

Flag user to force relogin

You can add an additional column force_relogin to User identity class and set it to true when you need to logout someone:

$user = User::findByLogin('userB');
$user->force_logout = 1;
$user->save();

Then add the event handler beforeLogin() on user component like so:

'user' => [
    'class' => 'yii\web\User',
    'on beforeLogin' => function ($event) {
        if ($event->identity->force_logout && $event->cookieBased) {
            $event->isValid = false;
        }
    },
    'on afterLogin' => function ($event) {
        if ($event->identity->force_logout) {
            $event->identity->force_logout = false;
            $event->identity->save();
        }
    }
]

Check, whether $cookieBased and $identity->force_logout are so on...

But that's a bad idea, because the user may have more than one session (logged in in different browsers)

Store list user's sessions in DB

Create table user_sessions with user_id and session_id columns and save each session, you open for that user in the DB. That you can find all sessions of the user and drop them one by one. Something like: (code is not tested, just as an idea)

$sessionId = Yii::$app->session->getId();
session_commit();
foreach (UserSessions::findByUserLogin('userB') as $session) {
   session_id($session->id);
   session_start();
   session_destroy();
   session_commit();
}

session_id($sessionId); // Restore original session
session_start();
session_commit();

The idea is weak because you always should take care about consistence of sessions on the server and in the DB.

Store sessions in DB

Store sessions is the database, as described in the Yii2 Guide for Session handling

Then you can just find session in the DB and delete it directly. You shouldn't take care about the consistence and session rotation, because DB is the only place, where the sessions are being stored. As a free bonus you get a non-blocking work with sessions.

Upvotes: 16

Related Questions