J.K.A.
J.K.A.

Reputation: 7404

Yii2 controller not allowing another action to guest user

I'm using Yii2 Advance application. I've SiteController.php where I've actions like login, logout & index. Here login is for Guest users and index & logout for logged-in users. Now I've created one more action called reset to provide Forgot Password functionality. But whenever I'm trying to call reset action its redirecting back me to login page.

Following is my controller:

namespace backend\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use common\models\LoginForm;
use yii\filters\VerbFilter;

/**
 * Site controller
 */
class SiteController extends Controller {

    /**
     * @inheritdoc
     */
    public function behaviors() {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['login', 'error'],
                        'allow' => true
                    ],
                    [
                        'actions' => ['logout', 'index'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['reset'],
                        'roles' => ['?'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post', 'get'],
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions() {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }

    public function actionIndex() {
        return $this->render('index');
    }

    public function actionLogin() {
        $this->layout = 'guest';

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

        $model = new LoginForm();

        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', [
                        'model' => $model,
            ]);
        }
    }

    public function actionLogout() {
        Yii::$app->user->logout();
        return $this->goHome();
    }

    public function actionReset() {        
        return $this->render('reset');
    }

}

I've added proper roles & behaviours for it but still its not working. I tried adding few more actions as well but in-fact its not allowing me to render any other action except login.

Any help would be appreciated.

Upvotes: 0

Views: 1615

Answers (2)

Muhammad Shahzad
Muhammad Shahzad

Reputation: 9652

Try this:

<?php
namespace backend\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;

    class SiteController extends Controller
    {
        /**
         * @inheritdoc
         */
        public function behaviors()
        {
            return [
                'access' => [
                    'class' => AccessControl::className(),
                    'rules' => [
                        [
                            'actions' => ['login', 'error', 'reset'],
                            'allow' => true,
                        ],
                        [
                            'actions' => ['logout', 'index'],
                            'allow' => true,
                            'roles' => ['@'],
                        ],

                    ],
                ],
                'verbs' => [
                    'class' => VerbFilter::className(),
                    'actions' => [
                        'logout' => ['post'],
                    ],
                ],
            ];
        }

 /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
       public function actionReset(){
            //die('You are here');
            return $this->render('reset');
        }

    ...
    }

My reset view code:

<?php

/* @var $this yii\web\View */
/* @var $name string */
/* @var $message string */
/* @var $exception Exception */

use yii\helpers\Html;

$this->title = "Reset";
?>
<div class="site-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <div class="alert alert-success">
        Hi here you are without login
    </div>


</div>

enter image description here

Upvotes: 1

J.K.A.
J.K.A.

Reputation: 7404

Solved it myself :)

There's condition in vendor/yiisoft/yii2/web/Controller.php i.e.

if($this->action->id != 'login') { .. }

And I changed it to

if($this->action->id != 'login' && $this->action->id != 'reset') { .. }

i.e.

public function beforeAction($action)
{ 
    // If user is guest then redirect to login page
    if($this->action->id != 'login' && $this->action->id != 'reset') {
        if(!isset($_SESSION['__id'])) {
           $this->redirect(array('site/login'));   
       }
    }
    if (parent::beforeAction($action)) {
        if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
            throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
        }
        return true;
    } else {
        return false;
    }
}

And its working.

Upvotes: 1

Related Questions