yii2-usuario
yii2-usuario copied to clipboard
How to permit backend only to administrators?
Using the yii2-app-advanced application template, I'd like to allow the whole backend only to administrators. I have secured the backend now, so that only the login is possible (no password reset, no registration, ...). For that I'm using the this application configuration (backend/config/main.php), so I don't have to declare the rules in each controller:
'as globalAccessController' => [
'class' => AccessControl::class,
'rules' => [
// the only callable action for not logged-in users
[
'allow' => true,
'roles' => ['?'],
'actions' => ['login'],
'controllers' => ['user/security'],
],
// error page should be possible anyway
[
'allow' => true,
'actions' => ['error'],
'controllers' => ['site'],
],
// yii debug toolbar should always be accessible (if activated)
[
'allow' => true,
'controllers' => ['debug/*'],
],
// all other actions can only be called by logged-in users
[
'allow' => true,
'roles' => ['@'], // 'roles' => ['administrator'] ???
],
],
],
Changing the last rule to 'roles' => ['administrator'] should do it. However, other users are still able to to log in though, but each page shows a 403 error page.
How can I do it the right way, so that only administrators can log in. Is it necessary to override the default SecurityController? Is there a better approach than the global access control configuration?
What I've done to have the same:
- Created a Role "WebAdmins" and assign it to users that need to have access to backend
- in backend/config/main.php i've added the following in 'modules' part
'controllerMap' => [ 'security' => [ 'class' => \Da\User\Controller\SecurityController::class, 'on ' . \Da\User\Event\FormEvent::EVENT_AFTER_LOGIN => function (\Da\User\Event\FormEvent $event) { $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId()); foreach($roles as $k => $role){ if($k === "WebAdmins"){ \Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('')); \Yii::$app->end(); } } \Yii::$app->user->logout(true); \Yii::$app->controller->redirect(Yii::$app->urlManagerFrontend->createUrl('/user/security/login')); \Yii::$app->end(); } ], ], - Also here in main.php in 'components' part I've added the following
'urlManagerFrontend' => [ 'class' => 'yii\web\urlManager', 'baseUrl' => '@web/../', 'enablePrettyUrl' => true, 'showScriptName' => false, ],After user logs in the system automatically logs him out and redirects to login page on front side.
Maybe there is a better approach and will be glad to see another solutions.
P.S. the code does not formats well, but you could figure out.
Thank you @EndErr for that. Seems to work. Just the urlManagerFronend is confusing me a bit, since I don't have a @web. Now I just use the default urlManager, so that the user gets redirected to the login page of the backend.
Little optimization that hopefully is the same as your suggestion:
'controllerMap' => [
'security' => [
'class' => SecurityController::class,
'on ' . FormEvent::EVENT_AFTER_LOGIN => function (FormEvent $event) {
$roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
if (array_key_exists(Yii::$app->modules['user']->administratorPermissionName, $roles)) {
Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl(''));
Yii::$app->end();
}
Yii::$app->user->logout(true);
Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('/user/security/login'));
Yii::$app->end();
}
],
],
btw: In order to format code, using syntax highlighting for php, use this in your postings (first and last line are essential):
```php
'controllerMap' => [
'security' => [
'class' => SecurityController::class,
'on ' . FormEvent::EVENT_AFTER_LOGIN => function (FormEvent $event) {
$roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
if (array_key_exists(Yii::$app->modules['user']->administratorPermissionName, $roles)) {
Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl(''));
Yii::$app->end();
}
Yii::$app->user->logout(true);
Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('/user/security/login'));
Yii::$app->end();
}
],
],
```
for some days after a update $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId()); returns a empty array
any thoughts?
What update? Is it related to this bug?
not sure, just did a composer update and after that couldn't login to backend
digging found that Yii::$app->user->getId() in above code returns nothing