Yii 1.1: Using loginRequiredAjaxResponse to solve ajax session timeout

16 followers

This solution requires Yii 1.1.9 or above

The problem:

A user has no activity for a longer period of time and the php session times out. After the session has expired he makes an Ajax request and nothing happens or, in case of a grid view, the grid completely disappears.

Expected behavior:

Show the login page and redirect after successful login

The solution:

Set 'loginRequiredAjaxResponse' in your configuration (config/main.php)

...
'components'=>array(
    'user'=>array(          
        ...
        'loginRequiredAjaxResponse' => 'YII_LOGIN_REQUIRED',
        ...
    ),
    ...

In your view or template

<?php
    if (Yii::app()->components['user']->loginRequiredAjaxResponse){
        Yii::app()->clientScript->registerScript('ajaxLoginRequired', '
            jQuery("body").ajaxComplete(
                function(event, request, options) {
                    if (request.responseText == "'.Yii::app()->components['user']->loginRequiredAjaxResponse.'") {
                        window.location.href = options.url;
                    }
                }
            );
        ');
    }
?>

Note:

The code above is tested with a grid view where options.url is a useable page url. If this is not the case or you just want to show the login page with no redirect afterwards you can replace

window.location.href = options.url;

with

window.location.href = "'.Yii::app()->createUrl('/site/login').'"

Total 3 comments

#11628 report it
Enom at 2013/01/23 02:21pm
Return Page and Pre 1.9

Be mindful that using options.url will redirect you to the AJAX call(obviously). This might not be what you when using a CHtml::ajaxButton() and an actionAjax() since - for example - you'll only see a JSON response. To fix this and go back to the proper page I used the following:

window.location.href = "'.Yii::app()->getRequest()->getRequestUri().'"
// Or even simpler
window.location.reload(true)

As for pre 1.9 releases, you'll need to add the following code to WebUser:

public $loginRequiredAjaxResponse;
 
public function loginRequired() {
    if (Yii::app()->request->getIsAjaxRequest()) {
        echo $this->loginRequiredAjaxResponse;
 
        Yii::app()->end();
    } else {
        parent::loginRequired();
    }
}

This worked for my AJAX buttons, I haven't tested it within list/grid views.

#9622 report it
Backslider at 2012/08/29 08:26pm
Using ajaxComplete is wrong

Using ajaxComplete is wrong, since the Ajax call may itself be using this, possibly leading to errors and thus failure to redirect. The redirect must happen before ajaxComplete.

ajaxSuccess is the correct event to use.

#7720 report it
yiqing95 at 2012/04/11 09:58am
since 1.9 , loginRequiredAjaxResponse can be used!

oh i found it is a new var introduced in yii 1.9 ! useful wiki ,by the way in ajax mode user should not be bring to another page to login ^-^ ; may be :

window.location.href = options.url;

this is a js code ,so we can do anything to replacing it ; we can use some lightBox to load a login form and do ajax login ,after success just reload the gridview/listview data

Leave a comment

Please to leave your comment.

Write new article