Im tying to use the command sequence:
Yii::app()->user->setFlash('success', "Successful!");
Yii::app()->user->logout();
$this->redirect(array('user/login'));
The user got logged out and redirected, but the Setflash does not work.
I also tried to change the order of 2 frist commands, but got the same problem.
If I do not logout the user, the Setflash works fine.
How can I make both commands work?
this should work
Yii::app()->user->logout();
Yii::app()->session->open();
Yii::app()->user->setFlash(...);
If you need to destroy a whole session but you want to set a flash afterwards, you may extends CWebUser this way:
<?php
class BaseWebUser extends CWebUser
{
public function logout($destroySession = true)
{
parent::logout($destroySession);
Yii::app()->session->open();
}
}
?>
have a closer look here
I think you can use this :
public function afterLogout() {
// Create new session
$session=new CHttpSession;
$session->open();
// Set flash message
Yii::app()->user->setFlash('success', 'You are logged out successfully.');
// Prepare target URL after logout
$continue_url = Yii::app()->request->hostInfo . Yii::app()->createUrl('');
// Redirect
CController::redirect($continue_url);
}
Put it inside your WebUser components.
Flash messages are stored in the session. Logging the user our destroys the user's current session. Once session_destroy() is called, you must call session_start() again in order to generate a new session ID and have this work. Yii most likely does not do that.
If it's that important that you have a "Successful" message indicating that the logout worked - then redirect the user to a "logout successful" page. Alternatively, you can look into overriding the way Yii performs a logout - although I wouldn't recommend it.
Related
I wanted to logout a user session logged in a different browser/environment from the current session of the same user. A feature similar to this - https://www.facebook.com/settings?tab=security§ion=sessions&view.
Yii2 is the backend framework used. Using redis for session management - yii2-redis. I also save the session ids saved in database.
I followed this article -
http://www.codeinphp.com/general/php-code-snippets/remotely-destroy-different-session-php-forced-user-signout/
But didn't had any success.
session_id($old_session_id);
session_start(); // This line throws error.
session_destroy();
Deleting the key in redis using \Yii::$app->session->destroySession($oldSessionId) didn't logout.
Changing the session id to old one and then destroying the session also didn't work.
$currentSessionId = \Yii::$app->session->getId();
\Yii::$app->session->setId($oldSessionId);
\Yii::$app->getSession()->destroy();
\Yii::$app->session->setId($currentSessionId);
If anyone had success in implementing this successfully, please share your solution. Also if there is any documentation regarding this which can help, please do provide.
The first, session_start() must be call before session_id() and just call only once
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
session_id($old_session_id);
session_destroy();
But just remove session, that is not enough if you allow user auto login because browser will auto login by using cookies. To solve, you must change user AuthKey - Yii2 use AuthKey to validate user auto login. By default each user have only one AuthKey in user table so that when you change AuthKey user logout anywhere. So we have to custom. Create for each user session an AuthKey, stored somewhere not in user table. Do it easy: extends yii\web\User class override afterLogin function to create AuthKey for each login session. override validateAuthKey function to validate auto login use our custom AuthKey. Now when you want to kill any user session : kill PHP session id and AuthKey that session will be logout right away.
I have been using this solution for my projects and it works fine.
Based on Ngo's answer, I figured out a method that works well and is easier to setup.
1) Add a "last_session_id" field to your user table.
2) Add following to your main controller:
public function afterAction($action, $result)
{
$result = parent::afterAction($action, $result);
if(Yii::$app->user->id)
{
//update the user table with last_session_id
$user = User::find()->where(['id' => Yii::$app->user->id])->one();
$user->last_session_id = Yii::$app->session->id;
$user->save(false);
}
return $result;
}
3) Change site/login action to following:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
//delete previous session ID and change auth key
Yii::$app->session->destroySession(Yii::$app->user->identity->last_session_id);
$u = \common\models\User::find()->where(['id' => Yii::$app->user->id])->one();
$u->auth_key = Yii::$app->security->generateRandomString();
$u->save(false);
return $this->goBack();
} else {
return $this->render('/site/login', [
'model' => $model,
]);
}
}
I've try to use $this->session->set_flashdata('success') and it's not working after redirect to another function. Here is my code:
<?php
class Home extends CI_Controller{
public function __construct(){
parent::__construct();
$this->load->helper(array('url','form');
$this->load->library(array('session','template','form_validation');
}
}
/* My another function for form_validation and etc */
public function login(){
$this->set_login_rules();
if($this->form_validation->run()){
/* inserting data to database */
$this->session->set_flashdata('welcome');
redirect('home/welcome');
}
$this->template->display('home');
}
public function welcome(){
if($this->session->flashdata('welcome') !== FALSE){
echo "<script>alert('Flashdata Success! Welcome!</script>";
}
else{
echo "<script>alert('Flashdata Failed! Go Away!');</script>";
}
}
when I run the program, it shows alert Flashdata Failed! Go Away!
but the login data that I want to insert to database is added into the table.
one more thing, sometimes the flashdata is working. From 10 tries, 8-9 tries if show Flashdata Failed! Go Away!.
Can anybody tell me why this happend? And how can I fixed it?
You actually need to give some value to it, so:
$this->session->set_flashdata('welcome');
should be:
$this->session->set_flashdata('welcome', true);
or you can use the full message for example:
$this->session->set_flashdata('welcome', 'Successfully logged in');
etc...
See more info about flashdata here: https://ellislab.com/codeigniter/user-guide/libraries/sessions.html
From the Codeigniter documentation:
CodeIgniter supports "flashdata", or session data that will only be available for the next server request, and are then automatically cleared.
Your problem might be that when you redirect, the process takes more than one request, that clearing your flashdata.
Use regular session or query parameter.
I want to force a user to logout when I change it's status to 'inactive' using session in codeigniter.
I used the method below, but it destroyed my own session:
function deactivate($user_Id)
{
$this->session->unset_userdata(array('user_Id' => $user_Id));
}
I happened to need this feature implemented and here is how I did it:
record user session id as last_active_session in db after login
find that session id and delete it from session table when this user is banned or anything.
You can also use this to prevent concurrent login such as the last successful login user bump the previous one.
Use the sess_destroy() method instead:
function deactivate() {
$this->session->sess_destroy();
}
From my application view I need to programmatically logout current user and login another one right after that.
I want to login the second user into his own different CHttpSession (with another sessionID and so on). I need it for a security reasons.
How to implement this in Yii framework ?
Code below
$oSession->destroy();
$oSession->open();
doesn't work as expected..
looks like you are trying to impersonate users:
Create a function in your UserIdentity that would alow you to login as another known user:
protected function logInUser($user)
{
if($user)
{
$this->_user = $user;
$this->_id=$this->_user->id;
$this->setState('name', $this->_user->name);
$this->errorCode=self::ERROR_NONE;
}
}
In your controller, call this function to get the UserIdentity object and then use the Yii's CWebUser login
$ui = null;
$user = User::model()->findByPk($userId);
if($user)
{
$ui = new UserIdentity($user->email, "");
$ui->logInUser($user);
}
Yii::app()->user->login($ui, 0);
Remember to protect this controller's action from non authorized users.
A possible tricky way (tested):
session_unset();
Yii::app()->user->id = $the_new_id;
When the above code is executed, nothing visible happens on the page so you may want to redirect the browser:
$this->redirect('somewhere');
Upon the next page load, the user with the $the_new_id will be logged in
I have a logout controller in codeigniter :
<?php
class Logout extends MY_Controller {
function index()
{
$this->session->sess_destroy();
redirect('index.php');
}
}
This logs me out but when i call another controller after logging, like "/site/addnewpost",
this just logs me in again, as if the sassion had not been destroyed previously. Why is this happening?
Follow ALex's suggestion, but using CI code:). What I mean, try unsetting each session data individually. I read once about an issue in version 2.0.3 I think, but I don't remember now and I don't have time to search for the reference. It's in their forum, though, and the suggestion was the same: unset each session element one by one.
$this->session->unset_userdata('data_one');
$this->session->unset_userdata('data_two');
$this->session->unset_userdata('data_three');
$this->session->unset_userdata('data_one');
$this->session->sess_destroy();
redirect('home','refresh'); // <!-- note that
//you should specify the controller(/method) name here
You need to redirect because CI's session are just cookies, not the native php session array.
Another thing...make sure the fault isn't in your login methods, which logs you in no matter if you succesfully logout or not!
Try explicitly delete items like this:
$this->Session->delete('User');
$this->Session->destroy();
$this->Cookie->delete("User");
$this->Cookie->destroy();
$this->Auth->logout();
$this->redirect('whereever');
My problem had to do with caching on the server side. The quickest I could fix it was by appending random text to the logout link:
<?php
$this->load->helper('string');
echo anchor('/home/logout/'.random_string(), 'logout');
?>
home/logout contained the same code as function index in the question.
Just so you know the redirect('/', 'refresh') did not work for me, but I again I did a quick test.
I am guessing that the random_string() method can be replaced by outputting headers that force cache to be cleared etc. As you have probably guessed, I can't do that right now as I am super busy. Maybe later.
You can also try manually setting your "logged_in" or whatever you called the session to false. Then, destroying all other session data.
$this->session->set_userdata('logged_in', FALSE);
$this->session->session_destroy();
redirect('index');
first we have to load session library to deal with session than unset the sessionID and destroy the session. I am using this code to unset my session and secure logout.
$this->load->library('session');
$this->session->set_userdata('user_id', FALSE);
$this->session->sess_destroy();
$this->load->view('your URL');