Аутентификация в Yii2: короткое руководство для старта
Как поднять вход по логину и паролю в Yii2 с нуля: настройка компонента user, интерфейс IdentityInterface, форма входа и проверка, что сессия действительно живёт.

К концу этого руководства у вас будет рабочий вход по логину и паролю в приложении на Yii2 (2.0.x): пользователь заполняет форму, приложение проверяет пароль по хешу из базы, а дальше Yii::$app->user->identity возвращает залогиненного пользователя на любой странице. На всё уйдёт примерно 30–40 минут, если проект уже развёрнут.
Разбираем только классическую сессионную аутентификацию через компонент user. RBAC (роли и права), вход через соцсети и токены для REST — это отдельные темы, здесь их не трогаем.
Что нужно иметь до начала
- Установленный Yii2 версии 2.0.x — подойдёт как basic-, так и advanced-шаблон. Примеры ниже под basic; в advanced логика та же, но классы лежат в каталоге
common/models. - PHP 7.4 или новее и настроенное подключение к базе (компонент
dbв конфиге). - Таблица пользователей. Если её нет — создадим ниже через миграцию.
- Доступ к консоли для запуска
./yiiи миграций.
Проверьте, что базовое приложение открывается в браузере и выдаёт стартовую страницу. Если нет — сначала почините окружение, аутентификация тут ни при чём.
Как это устроено в Yii2
Аутентификацией занимается компонент user (класс yii\web\User). Он не знает, где лежат ваши пользователи и как проверять пароль — за это отвечает класс идентичности, который вы назначаете в конфиге. Класс должен реализовать интерфейс yii\web\IdentityInterface.
Компонент user — это про сессию и «кто сейчас вошёл». Модель Identity — про то, откуда взять пользователя и как сверить пароль. Не смешивайте эти роли: вся логика проверки пароля живёт в модели, а не в контроллере.
Identity-класс обязан реализовать пять методов: findIdentity(), findIdentityByAccessToken(), getId(), getAuthKey() и validateAuthKey(). Для сессионного входа реально работают findIdentity(), getId() и пара с authKey (нужна для «запомнить меня»).
Шаг 1. Таблица и миграция
Если таблицы пользователей ещё нет, создайте миграцию:
./yii migrate/create create_user_table
В сгенерированном файле миграции опишите структуру. Минимальный набор полей:
<?php
use yii\db\Migration;
class m240101_000000_create_user_table extends Migration
{
public function safeUp()
{
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string(64)->notNull()->unique(),
'password_hash' => $this->string(255)->notNull(),
'auth_key' => $this->string(32)->notNull(),
'created_at' => $this->integer()->notNull(),
]);
}
public function safeDown()
{
$this->dropTable('{{%user}}');
}
}
Примените миграцию:
./yii migrate
Проверка: команда завершится строкой Migrated up successfully., а в базе появится таблица user.
Шаг 2. Модель User с IdentityInterface
Создайте файл models/User.php. Пароли храним только как хеш — Yii даёт для этого встроенные методы Yii::$app->security->generatePasswordHash() и validatePassword().
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return '{{%user}}';
}
// Поиск пользователя по id из сессии
public static function findIdentity($id)
{
return static::findOne(['id' => $id]);
}
// Для токенов; при сессионном входе не используется
public static function findIdentityByAccessToken($token, $type = null)
{
return null;
}
public static function findByUsername($username)
{
return static::findOne(['username' => $username]);
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->auth_key;
}
public function validateAuthKey($authKey)
{
return $this->auth_key === $authKey;
}
// Проверка введённого пароля против хеша
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
// Установка пароля при регистрации
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
}
Проверка: откройте ./yii в консоли — приложение не должно ронять фатальную ошибку из-за синтаксиса. Если PHP ругается на класс, ищите незакрытую скобку или неверный namespace.
Шаг 3. Подключаем модель в конфиге
В config/web.php в секции components укажите ваш класс идентичности:
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
Параметр enableAutoLogin включает «запомнить меня» через cookie — именно для него нужен auth_key. Если функция не нужна, поставьте false.
Шаг 4. Форма входа
Создайте models/LoginForm.php — отдельную модель формы, а не саму модель User. Она валидирует ввод и вызывает вход.
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class LoginForm extends Model
{
public $username;
public $password;
public $rememberMe = true;
private $_user = false;
public function rules()
{
return [
[['username', 'password'], 'required'],
['rememberMe', 'boolean'],
['password', 'validatePassword'],
];
}
// Кастомный валидатор: сверяем пароль
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Неверный логин или пароль.');
}
}
}
public function login()
{
if ($this->validate()) {
// 3600 * 24 * 30 — срок жизни cookie при rememberMe
$duration = $this->rememberMe ? 3600 * 24 * 30 : 0;
return Yii::$app->user->login($this->getUser(), $duration);
}
return false;
}
public function getUser()
{
if ($this->_user === false) {
$this->_user = User::findByUsername($this->username);
}
return $this->_user;
}
}
Обратите внимание: сообщение об ошибке одно и то же и для несуществующего логина, и для неверного пароля. Это не косметика, а защита — не подсказывайте, какой именно логин существует в базе.
Шаг 5. Действие контроллера
В controllers/SiteController.php добавьте действия входа и выхода:
use Yii;
use app\models\LoginForm;
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
$model->password = '';
return $this->render('login', ['model' => $model]);
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
Шаблон views/site/login.php с формой в basic-приложении уже есть по умолчанию; если вы его удаляли, соберите форму через ActiveForm с полями username, password и чекбоксом rememberMe.
Проверка: заведите тестового пользователя (через консольную команду, seed или руками в базе с хешем из generatePasswordHash), откройте /site/login, введите данные. При верном пароле вас перебросит на главную, при неверном появится «Неверный логин или пароль.» под полем.
Как убедиться, что вошли по-настоящему
Проверьте на любой странице:
Yii::$app->user->isGuestвернётfalseпосле входа;Yii::$app->user->identityвернёт объектUser, аYii::$app->user->id— его id;- в браузере в куках появится сессионный идентификатор, а при
rememberMe— дополнительная cookie_identity.
Чтобы закрыть страницу только для вошедших, добавьте в контроллер поведение AccessControl из yii\filters\AccessControl с правилом 'roles' => ['@'] — символ @ означает «любой аутентифицированный».
Если не получилось
- «Class 'app\models\User' does not exist» — не совпадает namespace или путь к файлу. В basic-шаблоне namespace модели должен быть
app\models, файл — в каталогеmodels. - Вход не сохраняется, после перехода снова гость — чаще всего слетает сессия: проверьте права на каталог
runtimeи что PHP может писать сессии. ТакжеenableAutoLoginбез заполненногоauth_keyв базе даст сброс при закрытии вкладки. - «Call to a member function validatePassword() on null» —
findByUsernameвернулnull, а вы обратились к результату напрямую. В коде выше это закрыто проверкой!$user, не убирайте её. - Пароль верный, но вход не проходит — вероятно, в базе лежит пароль в открытом виде или хеш, созданный не через
generatePasswordHash. Пересоздайте хеш встроенным методом. - Ошибка CSRF при отправке формы — используйте
ActiveForm, он сам добавляет скрытое поле токена. При ручной вёрстке формы токен нужно вставлять самому.
Что делать дальше
Базовый вход работает — дальше по потребности:
- ограничьте доступ к страницам через
AccessControlи, если ролей несколько, подключите RBAC (authManager); - для API вместо сессии используйте
HttpBearerAuthи методfindIdentityByAccessToken(), который сейчас возвращаетnull; - добавьте регистрацию и подтверждение email, флаг
statusдля блокировки, сброс пароля через токен.
Точные сигнатуры компонента user, фильтров доступа и класса Security сверяйте с официальным руководством по вашей версии Yii2 — API стабилен внутри ветки 2.0.x, но детали параметров лучше читать в документации, а не по памяти.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Yii2 Guide — Authentication, Yii2 API — yii\web\IdentityInterface
Частые вопросы
У меня advanced-шаблон, а не basic. Что менять?
Обязательно ли поле auth_key, если «запомнить меня» мне не нужно?
Вход проходит, но на следующей странице пользователь снова гость. Почему?
Можно ли хранить пароль без хеша, чтобы было проще на тесте?
Отличается ли этот код между версиями Yii2?
Как создать первого пользователя, если формы регистрации ещё нет?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.