Аутентификация - это процесс проверки личности пользователя. Обычно он использует идентификатор (например, имя пользователя или адрес электронной почты) и секретный токен (например, пароль или токен доступа), чтобы судить, является ли пользователь тем, на кого он претендует. Аутентификация - это основа функции входа в систему.

Yii предоставляет схему проверки подлинности, которая поддерживает различные компоненты для поддержки входа в систему. Чтобы использовать эту инфраструктуру, вам необходимо выполнить следующую работу:

  • Настроить компонент пользовательского приложения;
  • Создайте класс, который реализует интерфейс yii\web\IdentityInterface

Настройка yii\web\User

Пользовательский компонент приложения управляет статусом аутентификации пользователя. Он требует указать класс идентификации, который содержит фактическую логику аутентификации. В следующей конфигурации приложения класс идентификации для пользователя настроен как app\models\User:

return [
    'components' => [
        'user' => [
            'identityClass' => 'app\models\User',
        ],
    ],
];

Внедрение yii\web\IdentityInterface

Класс identity должен реализовывать yii\web\IdentityInterface, который содержит следующие методы:

  • findIdentity(): ищет экземпляр класса идентификации с использованием указанного идентификатора пользователя. Этот метод используется, когда вам нужно сохранить статус входа в сеансе.
  • findIdentityByAccessToken(): ищет экземпляр класса identity с использованием указанного токена доступа. Этот метод используется, когда вам нужно пройти аутентификацию пользователя по одному секретному токену (например, в приложении RESTful без сохранения состояния).
  • getId(): возвращает идентификатор пользователя, представленного этим экземпляром идентификации.
  • getAuthKey(): возвращает ключ, используемый для проверки имени пользователя на основе cookie. Ключ хранится в куки-файле входа, и позже его сравнивают с версией на стороне сервера, чтобы убедиться, что cookie для входа действителен.
  • validateAuthKey(): он реализует логику проверки ключа для входа в файл cookie.

Если какой-то конкретный метод не нужен, вы можете реализовать его с пустым телом. Например, если ваше приложение представляет собой чистое приложение RESTful без сохранения состояния, вам нужно будет реализовать findIdentityByAccessToken() и getId(), оставив все остальные методы с пустым телом.

В следующем примере класс тождественности реализован как класс Active Record, связанный с таблицей user в базе данных.

<?php

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    public static function tableName()
    {
        return 'user';
    }

    /**
     * Finds an identity by the given ID.
     *
     * @param string|int $id the ID to be looked for
     * @return IdentityInterface|null the identity object that matches the given ID.
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    /**
     * Finds an identity by the given token.
     *
     * @param string $token the token to be looked for
     * @return IdentityInterface|null the identity object that matches the given token.
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    /**
     * @return int|string current user ID
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string current user auth key
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @param string $authKey
     * @return bool if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

Как объяснялось ранее, вам нужно только реализовать getAuthKey() и validateAuthKey(), если ваше приложение использует функцию входа в cookie. В этом случае вы можете использовать следующий код для генерации ключа аутентификации для каждого пользователя и хранения его в таблице user:

class User extends ActiveRecord implements IdentityInterface
{
    ......

    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}

Использование yii\web\User

В основном вы используете yii\web\User с точки зрения компонента пользовательского приложения.

Вы можете определить личность текущего пользователя, используя выражение Yii::$app->user->identity. Он возвращает экземпляр класса идентификации, представляющий текущего пользователя, или значение null, если текущий пользователь не аутентифицирован (имеется в виду гость). Следующий код показывает, как получить другую информацию, связанную с проверкой подлинности, из yii\web\User:

// the current user identity. `null` if the user is not authenticated.
$identity = Yii::$app->user->identity;

// the ID of the current user. `null` if the user not authenticated.
$id = Yii::$app->user->id;

// whether the current user is a guest (not authenticated)
$isGuest = Yii::$app->user->isGuest;

Для входа в систему вы можете использовать следующий код:

// find a user identity with the specified username.
// note that you may want to check the password if needed
$identity = User::findOne(['username' => $username]);

// logs in the user
Yii::$app->user->login($identity);

Метод yii\web\User::login() устанавливает идентификатор текущего пользователя в yii\web\User. Если сеанс включен, он будет сохранять идентификатор в сеансе, чтобы статус аутентификации пользователя поддерживался на протяжении всего сеанса. Если включен вход в систему на основе файлов cookie, он также сохранит идентификатор в файле cookie, чтобы статус аутентификации пользователя можно было восстановить из файла cookie, пока cookie остается в силе.

Чтобы включить регистрацию на основе файлов cookie, вам нужно настроить yii\web\User::$enableAutoLogin, чтобы они были верны в конфигурации приложения. Кроме того, при вызове метода yii\web\User::login() необходимо указать параметр продолжительности.

Чтобы выйти из системы, используйте:

Yii::$app->user->logout();

Обратите внимание, что выход пользователя в систему имеет смысл только тогда, когда включен сеанс. Этот метод очистит статус аутентификации пользователя как в памяти, так и в сеансе. И по умолчанию он также уничтожит все данные сеанса пользователя. Если вы хотите сохранить данные сеанса, вам следует вместо этого использовать Yii::$app->user->logout(false).

События проверки подлинности

Класс yii\web\User вызывает несколько событий во время процессов входа и выхода из системы.

  • EVENT_BEFORE_LOGIN: поднят в начале yii\web\User::login(). Если обработчик события устанавливает свойство isValid объекта события как false, процесс входа в систему будет отменен.
  • EVENT_AFTER_LOGIN: поднят после успешного входа.
  • EVENT_BEFORE_LOGOUT: поднято в начале yii\web\User::logout(). Если обработчик события устанавливает свойство isValid объекта события как false, процесс выхода будет отменен.
  • EVENT_AFTER_LOGOUT: поднято после успешного выхода.

Вы можете реагировать на эти события, чтобы реализовать такие функции, как аудит входа, статистика онлайн-пользователей. Например, в обработчике EVENT_AFTER_LOGIN вы можете записать время входа и IP-адрес в таблице user.