'Yii2 redirecting to previous page after login

Hello World!

so here is the deal, i am trying to redirect the users after loginin' in to the previous page but it's not working .. i tried to use all of these :

Yii::$app->request->getReferrer(); // printing the refferrer url to screen 
$this->redirect(\Yii::$app->request->referrer)


 return \Yii::$app->getResponse()->redirect(\Yii::$app->getUser()->getReturnUrl($defaultUrl));

none of these above is working

 public function actionLogin()
    {
        if (!\Yii::$app->user->isGuest) {
                $this->goHome();
        //    $this->goHome();
        }

        /** @var LoginForm $model */
        $model = \Yii::createObject(LoginForm::className());
        $event = $this->getFormEvent($model);

        $this->performAjaxValidation($model);
       $baseurl = \Yii::$app->request->getAbsoluteUrl();
        $this->trigger(self::EVENT_BEFORE_LOGIN, $event);

        if ($model->load(\Yii::$app->getRequest()->post()) && $model->login()) {
            $this->trigger(self::EVENT_AFTER_LOGIN, $event);
           // return $this->redirect(\Yii::$app->request->referrer);
          //  return \Yii::$app->getResponse()->redirect(\Yii::$app->getUser()->getReturnUrl($defaultUrl));
           // return \Yii::$app->request->getReferrer(); // printing the refferrer url to screen :(!!
           return $this->redirect($baseurl);
         // return $this->redirect(\Yii::$app->request->referrer);; //this one is returning everthing to main page, because of line 147
          //  return $this->goBack();
        }

        return $this->render('login', [
            'model'  => $model,
            'module' => $this->module,
        ]);
    }


In the web.php config i have this :

$config =[ 
..//
'modules' => [
        'user' => [
            'class' => 'dektrium\user\Module',
            'enableUnconfirmedLogin' => true,
            'confirmWithin' => 21600,
            'cost' => 12,
            'enableFlashMessages' => true,
            'admins' => ['a'],
        ],
    //..

all of these above is just sending the user after login to the home page what should i do please , i have searched every where read the documentations

After 4 hours of trying i tried to "Echo" the URL after requesting referrer ; the referrer is working fine the problem is after login the page loads more than one time and here is the problem why it's not sending back to that page but sending people to the current page (login page) then if he is a user he is automatically sending home.



Solution 1:[1]

I did it, with the help of @serghei Leonenco,
but i had these problems :

  1. The page reloaded after pressing the button submit so the referrer was the login page always and this is why it kept sending users to main page.
  2. I had to get the referrer before the form begin.
  3. I had to pass the value of the referrer to a hidden input.
  4. I had to check if the referrer is from my website or the guest got on login page from a 3rd party site.
  5. Passed the value after checking, used redirect and Url::to('link', true) because the value i got from referrer was a full URL and i couldn't just redirect to a full link this is why i used Url::to with the true condition which means creating a new URL.

View

Notice that i used the referrer value before the form.

<div class="panel-body arab">
                **<?php $referer = \Yii::$app->request->referrer;?>**
                <?php $form = ActiveForm::begin([
                    'id' => 'login-form',
                    'enableAjaxValidation' => true,
                    'enableClientValidation' => false,
                    'validateOnBlur' => false,
                    'validateOnType' => false,
                    'validateOnChange' => false,
                ]) ?>
                **<?= $form->field($model, 'referer')->hiddenInput(['value' => $referer])->label(false) ?>**
                <?php if ($module->debug): ?>
                    <?= $form->field($model, 'login', [
                        'inputOptions' => [
                            'autofocus' => 'autofocus',
                            'class' => 'form-control',
                            'tabindex' => '1']])->dropDownList(LoginForm::loginList());
                    ?>

                <?php else: ?>

                    <?= $form->field($model, 'login',
                        ['inputOptions' => ['autofocus' => 'autofocus', 'class' => 'form-control', 'tabindex' => '1']]
                    );
                    ?>

                <?php endif ?>

                <?php if ($module->debug): ?>
                    <div class="alert alert-warning">
                        <?= Yii::t('user', 'Password is not necessary because the module is in DEBUG mode.'); ?>
                    </div>
                <?php else: ?>
                    <?= $form->field(
                        $model,
                        'password',
                        ['inputOptions' => ['class' => 'form-control', 'tabindex' => '2']])
                        ->passwordInput()
                        ->label(
                            Yii::t('user', 'Password')
                            . ($module->enablePasswordRecovery ?
                                ' (' . Html::a(
                                    Yii::t('user', 'Forgot password?'),
                                    ['/user/recovery/request'],
                                    ['tabindex' => '5']
                                )
                                . ')' : '')
                        ) ?>
                <?php endif ?>

                <?= $form->field($model, 'rememberMe')->checkbox(['tabindex' => '3']) ?>

                <?= Html::submitButton(
                    Yii::t('user', 'Sign in'),
                    ['class' => 'btn btn-success btn-block', 'tabindex' => '4']
                ) ?>

                <?php ActiveForm::end(); ?>
                

Model

Notice I used regex to make sure that the user got to login page using my website.

public function getReferer()
    {
        $getLink = \Yii::$app->request->post('login-form')['referer'];
        if(preg_match('/tajrobtak/', $getLink)){
        return $getLink;
        } else {
        return "";
        }
    }

Controller

 public function actionLogin()
    {
        if (!\Yii::$app->user->isGuest) {
            $this->goHome();
        }

        /** @var LoginForm $model */
        $model = \Yii::createObject(LoginForm::className());
        $referery = $model->getReferer();
        $event = $this->getFormEvent($model);

        $this->performAjaxValidation($model);

        $this->trigger(self::EVENT_BEFORE_LOGIN, $event);

        if ($model->load(\Yii::$app->getRequest()->post()) && $model->login()) {
            $this->trigger(self::EVENT_AFTER_LOGIN, $event);
            $this->redirect(Url::to($referery,true));
        }

        return $this->render('login', [
            'model'  => $model,
            'module' => $this->module,
        ]);
    }

Solution 2:[2]

The problem is common and it is related to the issue that at the time when you post login, your actual referrer is login page - actionLogin(), so you are redirected back again and off course you get passed throughout the condition that you are not the Guest. In order to handle this, you have to assign a referrer to a modal field, so it can be posted with the login information. So at the time when login is validated, you have the required referrer url in your field. Check if you have this field identified in your form:

<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?= $form->field($model, 'referer')->hiddenInput()->label(false) ?>

Controller

$form = new LoginForm();
//get previos viewed page url and store in the new model
$form->referer = Yii::$app->request->referrer;
if ($form->load(Yii::$app->request->post())) {
   if($form->login()){
      return $this->goBack((($form->referer) ? $form->referer : null));
   }
}

LoginForm() model

public $referer;
/**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            //...
            ['referer', 'string'],
        ];
    }

After that, when it will be post request, this field will contain a referrer, which you will pass in your controller.

Further, if you use the yii2-user module, now it is possible and necessary in the config in the controllerMap to remove all forced redirects for the event "after logging in" (I commented them out):

...
'modules' => [
        'user' => [
            'class' => \dektrium\user\Module::className(),
            'admins' => ['adminname'],
            'enableConfirmation' => false,
            'modelMap' => [
                'User' => 'app\models\User',
                'UserSearch' => 'app\models\UserSearch',
                'Profile' => 'app\models\Profile',
            ],
            'controllerMap' => [
                'profile' => 'app\controllers\user\ProfileController',
                'security' => [
                    'class' => \dektrium\user\controllers\SecurityController::className(),
                    'on ' . \dektrium\user\controllers\SecurityController::EVENT_AFTER_LOGIN => function ($e) {
                        /*if (Yii::$app->user->can('student free')) {
                            Yii::$app->response->redirect(array('/course'))->send();
                        }
                        if (Yii::$app->user->can('admin')) {
                            Yii::$app->response->redirect('http://site.ru/user/')->send();
                        }*/

                        //Yii::$app->response->redirect(Yii::$app->request->referrer)->send();
                    //    Yii::$app->response->redirect(array('/user/'.Yii::$app->user->id))->send();
                        //Yii::$app->end();
                    }
                ],
            ],
        ],
...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martijn Pieters
Solution 2