Yii url manager infinite redirect loop

2.1k Views Asked by At

I'm stuck with this one...

I have a Yii project (Yii 1.1.14) which runs fine on my local machine (IIS 7.5 with ISAPI rewrite 3, Php 5.5).

On the test server however (Linux, Apache 2.2, Php 5.5), everything works except redirecting. I'm getting an infinite redirect loop on the home page, because the login- und index-controllers are redirecting to each other, (which should not happen at all).

If I put the login action in the url (www.mysite.com/site/login), I can login. But, if I do a redirect in any controller action (e.g. after updating some data), I get thrown to the home url instead of the route I redirected to. It makes no difference if I use .htaccess rewrite rules, so I guess it must be some configuration in Yii combined with some apache-specific config stuff...

This is my urlManager config:

'homeUrl'=>array('/site/index'),
'components'=>array(
    'user'=>array(
        'loginUrl'=>array('site/login'),    
        // disable cookie-based authentication
        'allowAutoLogin'=>false,
        'class'=>'MyWebUser'    
    ),

    'urlManager'=>array(
        'urlFormat'=>'path',
        'showScriptName'=>false,
        'rules'=>array(
            '' => 'site/index',                  
            '<controller:\w+>/<id:\d+>'=>'<controller>/view',
            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
            '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
            '<module:\w+>/<controller:\w+>/<action:\w+>'=>'<module>/<controller>/<action>',
        ),
    ),
)

This is my .htaccess file:

Options +FollowSymLinks
RewriteEngine on
RewriteBase /
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
# RewriteRule . index.php
RewriteRule ^(.*)\?*$ index.php?$1 [L,QSA]

And my site/login and site/index actions which are causing an infinite loop (they do work as expected on my local machine):

public function actionIndex()
{
    if(Yii::app()->user->isGuest) {
        $this->redirect('/site/login');
    } else {
        $this->render('index');
    }
}

public function actionLogin()
{
    // redirect to index page if user is already logged in
    if(!Yii::app()->user->isGuest) {
        $this->redirect(Yii::app()->homeUrl);
    }

    $model = new LoginForm;

    // if it is ajax validation request
    if(isset($_POST['ajax']) && $_POST['ajax']==='login-form') {
        echo CActiveForm::validate($model);
        Yii::app()->end();
    }

    // collect user input data
    if(isset($_POST['LoginForm'])) {
        $model->attributes=$_POST['LoginForm'];
        // validate user input and redirect to the previous page if valid
        if($model->validate() && $model->login()) {
            $this->redirect(Yii::app()->user->returnUrl);
        }
    }
    // display the login form
    $this->render('login',array('model'=>$model));
}

Calling the routes directly works, redirecting does not.

Edit: when I switch from 'urlFormat'=>'path' to 'urlFormat'=>'get', routing works.

2

There are 2 best solutions below

1
On

I had a similar problem. In my case it was due to an error in the page. it was working in dev, but not in prod because different configuration of php. I got the infinite loop because in production I had removed the debug lines from index.php, so on error, it was redirecting to home, causing another error, and thus redirecting to home, causing error and so on.

I had resolved by putting the debug lines in production, fixing the error and removing the debug lines in production. Of course, in my case it was pre prod, if you are in actual production you may want to make all this test on a staging environment, not directly in production.

1
On

Instead of $this->redirect('/site/login');, try using $this->redirect(array('site/login'));