Alert Message Before Session Ends

I have been searching the forums but I haven’t found any related topic. I am trying to implement an alert that warns the user before the session ends. If he clicks the button in the alert message then the session will be renewed. Has anyone implemented something like this?

How can this be done?

You can use Yii’s flash messages or an extension like userflash.

Dear Friend

I found the solution.

But I hope there may be better solutions.

1.In main configuration file declare authTimeout.

main.php




'components'=>array(

		

		'user'=>array(

                        'allowAutoLogin'=>true,

			'authTimeout'=>300,  // 5 minutes.		

		),



2.In main layout file add a container to display flash messages.Preferrably before the main contents.

main.php




........................

<div id="timeout"></div> 

<?php echo $content; ?>

........................



3.Register the following script at the bottom of main layout file.

If we specifically set the authTimeout in CWebUser, CWebUser::updateAuthStatus regenerates

the authTimeout for every request for authenticated user.

We catch the authTimeout and updating it in the following script.

If user becomes idle, authTimeout will not be updated.

Then we are going to throw flash message 10 seconds before the specified timeout.It counts down to 0 second.

main.php




<?php

$user=Yii::app()->user;

if(!$user->getIsGuest())

{

   $time= ($user->getState(CWebUser::AUTH_TIMEOUT_VAR) - time()-10)*1000;//converting to millisecs

   Yii::app()->clientScript->registerSCript('timeoutAlert','

     setTimeout(function()

    {

	  var n=10;

	    setInterval(function()

	    {

		  if(n>0)$("#timeout").addClass("flash-error").text("Your session will expire in "+n+" seconds");

		  

		  if(n==0) {

			$("#timeout").text("Your session has expired!");clearInterval();

			     }

		--n;	

		},1000)	

	}, 

		

	'.$time.')

',CClientScript::POS_END);

}

?>



I added the alert message to the class flash-error.

Pop up windows with disabled background are much better option.

I hope somebody can make it better.

Regards.

seenivasan, thank you very much for the answer!

I will try your solution. The only thing missing is that the user should be able to click on the flash message to renew the session (without having to reload the webpage). Do you think something like a jquery link within the flash message will do the trick? the link would need to call another webpage in the background to renew the session and then close the flash message.

seenivasan, I already tried your solution and it worked OK. Then I did some modifications and now it is almost perfect:

  1. I am using twitter bootstrap’s modal window instead of the flash message.

  2. I added a button to the modal window with an ajax call to renew the session.

  3. If the session ends, it redirects the user to login page

here is the code:

views/layout/main.php





if(!user()->getIsGuest())

{

 $time= (user()->getState(CWebUser::AUTH_TIMEOUT_VAR) - time()-29)*1000;//converting to millisecs

 Yii::app()->clientScript->registerSCript('timeoutAlert',"

 var timeoutInterval;

 setTimeout(function()

    {

       $('#sessionModal').modal('show');

       var n=29;

       window.timeoutInterval=setInterval(function()

            {

                  if(n>0)$('#timeout').text('".t('index','Your session will expire in')." '+n+' ".t('index','seconds')."');

                  if(n==0) {

                        $('#timeout').text('Your session has expired!');

                        clearInterval(timeoutInterval);

                        $('#sessionModal').modal('hide');

                        document.location.href = '".url('site')."';

                  }

                --n;

            },1000)

        },

        $time)" ,CClientScript::POS_END);

}

?>


...





<div id="sessionModal" class="modal hide fade">

  <div class="modal-header">

    <h3><?php echo t('index','Your session is about to expire!') ?></h3>

  </div>

  <div id="timeout" class="modal-body">

    <?php echo t('index','Your session will expire in') . ' 30 '. t('index','seconds') ?>

   </div>

 <div class="modal-footer">

   <?php echo CHtml::ajaxButton (t('index','Renew session'),

          CController::createUrl('site/index'),

            array('success' => "function(){

                           window.timeoutInterval=clearInterval(window.timeoutInterval);  

                           $('#sessionModal').modal('hide');  }"),

            array('class'=>'btn btn-primary')

            );

  ?>

     </div>

  </div>



If the user clicks the Renwe session button then the session is renewed without reloading the page. The only thing is that if the user renews the session and stays idle, he does not get the alert message the second time (unless he refreshed the webpage).

Do you have a solution for this?

Thank you again

Hi seenivasan,

I have tried your solution and it works perfectly. Thanks for the solution.

Now the session expires when the user is idle every 5 mins.

My requirement was a bit different that the session should expire exactly at 5 mins whether the user is in idle state or not (should act moreover like a timer). Please let me know if you have a solution for this.

I was implementing similar functionality with user popup and here’s a bit of progress in the link below:

TImeout dialog when session end

Thanks.

Very useful piece of code. I have modified the code a little bit to get renew session message repeated time without refreshing whole page. Please see below…

Modified / appended code




<div id="sessionModal" class="modal show fade">

    <div class="modal-header">

        <h3><?php echo 'Your session is about to expire!'; ?></h3>

    </div>

    <div id="timeout" class="modal-body">

        <?php echo 'Your session will expire in 30 seconds.'; ?>

    </div>

    <div class="modal-footer">

        <?php 

            /*MODIFIED CODE START*/

            echo CHtml::ajaxButton('Renew session', 

                    CController::createUrl('site/renewSession'),

                    array('success' => "function(response) { 

                        window.timeoutInterval = clearInterval(window.timeoutInterval);

                        $('#sessionModal').modal('hide'); 

                        var timeoutInterval;

                        setTimeout(function()

                            {

                            $('#sessionModal').modal('show');

                            var n = 29;

                            window.timeoutInterval = setInterval(function()

                                {

                                if(n>0) $('#timeout').text('Your session will expire in" . " ' + n + ' " . 'seconds' . "');

                                if(n==0) {

                                    $('#timeout').text('Your session has expired!');

                                    clearInterval(timeoutInterval);

                                    $('#sessionModal').modal('hide');

                                    document.location.href = '" . CController::createUrl('site/index') . "';

                                }

                                --n;

                                }, 1000)

                            },parseInt(response));           

                    }"),

                    array('class' => 'btn btn-primary')

                    );

                    /*MODIFIED CODE END*/

        ?>

    </div>

</div>


<?php 

if(!Yii::app()->user->isGuest) {

    $time = (Yii::app()->user->getState(CWebUser::AUTH_TIMEOUT_VAR) - time() - 29) * 1000;

    Yii::app()->clientScript->registerScript('timeoutAlert',"

            var timeoutInterval;

            setTimeout(function()

                {

                    $('#sessionModal').modal('show');

                    var n = 29;

                    window.timeoutInterval = setInterval(function()

                        {

                            if(n>0) $('#timeout').text('Your session will expire in" . " ' + n + ' " . 'seconds' . "');

                            if(n==0) {

                                $('#timeout').text('Your session has expired!');

                                clearInterval(timeoutInterval);

                                $('#sessionModal').modal('hide');

                                document.location.href = '" . CController::createUrl('site/index') . "';

                            }

                        --n;

                    }, 1000)

            },

            $time)", CClientScript::POS_END);  

}

?>




And the site/renewSession action is




public function actionRenewSession()

	{

	    echo (Yii::app()->user->getState(CWebUser::AUTH_TIMEOUT_VAR) - time() - 29) * 1000;      

	}




Hope this will help.