Reputation: 1045
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
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
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
Reputation: 1592
Well, the problem is about how to kill all sessions of the user.
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)
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 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