Yii2 require all Controller and Action to login

Ngoun Thavy picture Ngoun Thavy · May 6, 2015 · Viewed 27.7k times · Source

In my sitecontroller I write like this

    'access' => [
        'class' => AccessControl::className(),
        'rules' => [
            [
                'actions' => ['login', 'error'],
                'allow' => true,
            ],
            [
                'actions' => ['logout', 'index' ,'call-back'], // add all actions to take guest to login page
                'allow' => true,
                'roles' => ['@'],
            ],
        ],
    ],

so If I go to index or call-back action,I'll redirected to login page. but I have to do it for all action to each controller. Could you tell me the best way to do it?

Answer

arogachev picture arogachev · May 6, 2015

Place this rule in the beginning of the rules section:

[
    'allow' => true,
    'roles' => ['@'],
],

Omitting the actions means all actions.

So your AccessControl config will be like this:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],

                // ...
            ],
        ],
    ];
}

Keep in mind that rules are applied in order they are declared.

To do it globally without inheritance, add the as beforeRequest array below (not inside!) the components declaration in your application config:

'components' => [ ... ],
'as beforeRequest' => [
    'class' => 'yii\filters\AccessControl',
    'rules' => [
        [
            'allow' => true,
            'actions' => ['login'],
        ],
        [
            'allow' => true,
            'roles' => ['@'],
        ],
    ],
    'denyCallback' => function () {
        return Yii::$app->response->redirect(['site/login']);
    },
],

This code will run before each request and block all actions except login for guests.

Make sure that there is no login action in other controllers than SiteController. If there are (and for example they are for different purposes), block them explicitly in according controllers. But it's pretty rare case.