Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Авторизация: фильтр AccessControl

Авторизация отвечает на вопрос «что этому пользователю разрешено». Аутентификация выяснила, кто вошёл; теперь нужно решить, можно ли ему создавать и менять статьи. Самый простой инструмент — фильтр AccessControl, который проверяет доступ до выполнения действия.

Где подключают фильтр

Фильтр подключают в методе behaviors() контроллера. Добавьте в controllers/PostController.php:

// controllers/PostController.php
use yii\filters\AccessControl;
 
public function behaviors(): array
{
    return [
        'access' => [
            'class' => AccessControl::class,
            'only' => ['create', 'update', 'delete'],
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
            ],
        ],
    ];
}

Выйдите с сайта и откройте /post/create — Yii перенаправит на страницу входа, а после входа вернёт обратно. Список и просмотр статей остаются открытыми: only перечисляет действия, к которым применяется фильтр.

Как читаются правила

Правила проверяются сверху вниз, срабатывает первое подходящее. Если не подошло ни одно, доступ запрещён.

Ключ правилаЗначение
allowtrue — разрешить, false — запретить
roles@ — вошедший пользователь, ? — гость, либо имя роли
actionsДействия, к которым относится правило
verbsМетоды запроса, например ['POST']
ipsАдреса посетителей

Разные правила для разных действий

'rules' => [
    [
        'allow' => true,
        'actions' => ['index', 'view'],
        'roles' => ['?', '@'],
    ],
    [
        'allow' => true,
        'actions' => ['create', 'update', 'delete'],
        'roles' => ['@'],
    ],
],

Без ключа only фильтр действует на все действия контроллера: читать статьи могут все, менять — только вошедшие. Действие, не упомянутое ни в одном правиле, закрыто для всех.

Что видит посетитель

Гостя Yii перенаправляет на адрес входа. Его задаёт свойство компонента user в config/web.php:

// config/web.php
'user' => [
    'identityClass' => 'app\models\User',
    'loginUrl' => ['site/login'],
],

Вошедший пользователь, которому доступ запрещён, получает ошибку 403 «Forbidden».

Проверка владельца

Фильтр не знает, чью статью открывают. Что менять статью может только её автор, проверяют в самом действии:

use yii\web\ForbiddenHttpException;
 
public function actionUpdate(int $id)
{
    $post = Post::findOne($id);
 
    if ($post === null) {
        throw new NotFoundHttpException('Статья не найдена.');
    }
 
    if ($post->user_id !== Yii::$app->user->id) {
        throw new ForbiddenHttpException('Это не ваша статья.');
    }
 
    // загрузка формы и сохранение
}

Чужую статью по адресу /post/update?id=7 изменить не получится: страница ответит ошибкой 403.

Ссылки в шаблоне

Кнопки, которыми посетитель не может воспользоваться, скрывают:

<?php
// views/post/view.php
 
use yii\helpers\Html;
?>
 
<?php if (!Yii::$app->user->isGuest && $post->user_id === Yii::$app->user->id): ?>
    <?= Html::a('Изменить', ['post/update', 'id' => $post->id]) ?>
<?php endif; ?>

Ссылку «Изменить» увидит только автор статьи.

Частая ошибка

Скрыть ссылку в шаблоне — не значит закрыть доступ. Адрес /post/update?id=7 можно набрать вручную, и без проверки в контроллере действие выполнится. Шаблон управляет удобством, а права проверяют фильтр и код действия.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.