Аутентификация ¶
Аутентификация — это процесс проверки подлинности пользователя. Обычно используется идентификатор
(например, username
или адрес электронной почты) и секретный токен (например, пароль или ключ доступа), чтобы судить о
том, что пользователь именно тот, за кого себя выдаёт. Аутентификация является основной функцией формы входа.
Yii предоставляет фреймворк авторизации с различными компонентами, обеспечивающими процесс входа. Для использования этого фреймворка вам нужно проделать следующее:
- Настроить компонент приложения user;
- Создать класс, реализующий интерфейс yii\web\IdentityInterface.
Настройка yii\web\User ¶
Компонент user управляет статусом аутентификации пользователя.
Он требует, чтобы вы указали identity class, который будет содержать
текущую логику аутентификации. В следующей конфигурации приложения, identity class для
user задан как app\models\User
, реализация которого будет объяснена в следующем разделе:
return [
'components' => [
'user' => [
'identityClass' => 'app\models\User',
],
],
];
Реализация yii\web\IdentityInterface ¶
identity class должен реализовывать yii\web\IdentityInterface, который содержит следующие методы:
- findIdentity(): Этот метод находит экземпляр
identity class
, используя ID пользователя. Этот метод используется, когда необходимо поддерживать состояние аутентификации через сессии. - findIdentityByAccessToken(): Этот метод находит экземпляр
identity class
, используя токен доступа. Метод используется, когда требуется аутентифицировать пользователя только по секретному токену (например в RESTful приложениях, не сохраняющих состояние между запросами). - getId(): Этот метод возвращает ID пользователя, представленного данным экземпляром
identity
. - getAuthKey(): Этот метод возвращает ключ, используемый для основанной на
cookie
аутентификации. Ключ сохраняется в аутентификационной cookie и позже сравнивается с версией, находящейся на сервере, чтобы удостоверится, что аутентификационнаяcookie
верная. - validateAuthKey(): Этот метод реализует логику проверки ключа
для основанной на
cookie
аутентификации.
Если какой-то из методов не требуется, то можно реализовать его с пустым телом. Для примера, если у вас RESTful приложение, не сохраняющее состояние между запросами, вы можете реализовать только findIdentityByAccessToken() и getId(), тогда как остальные методы оставить пустыми.
В следующем примере, identity class реализован
как класс 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;
}
}
Примечание: Не путайте
identity
классUser
с классом yii\web\User. Первый является классом, реализующим логику аутентификации пользователя. Он часто реализуется как класс Active Record, связанный с некоторым постоянным хранилищем, где лежит информация о пользователях. Второй — это класс компонента приложения, отвечающий за управление состоянием аутентификации пользователя.
Использование yii\web\User ¶
В основном класс yii\web\User используют как компонент приложения user
.
Можно получить identity
текущего пользователя, используя выражение Yii::$app->user->identity
. Оно вернёт экземпляр
identity class, представляющий текущего аутентифицированного пользователя,
или null
, если текущий пользователь не аутентифицирован (например, гость). Следующий код показывает, как получить
другую связанную с аутентификацией информацию из yii\web\User:
// `identity` текущего пользователя. `Null`, если пользователь не аутентифицирован.
$identity = Yii::$app->user->identity;
// ID текущего пользователя. `Null`, если пользователь не аутентифицирован.
$id = Yii::$app->user->id;
// проверка на то, что текущий пользователь гость (не аутентифицирован)
$isGuest = Yii::$app->user->isGuest;
Для залогинивания пользователя вы можете использовать следующий код:
// найти identity с указанным username.
// замечание: также вы можете проверить и пароль, если это нужно
$identity = User::findOne(['username' => $username]);
// логиним пользователя
Yii::$app->user->login($identity);
Метод yii\web\User::login() устанавливает identity
текущего пользователя в yii\web\User. Если сессии
включены, то identity
будет сохраняться в сессии, так что состояние
статуса аутентификации будет поддерживаться на всём протяжении сессии. Если включен вход, основанный на cookie (так называемый "запомни меня" вход), то identity
также будет сохранена
в cookie
так, чтобы статус аутентификации пользователя мог быть восстановлен на протяжении всего времени жизни cookie
.
Для включения входа, основанного на cookie
, вам нужно установить yii\web\User::$enableAutoLogin в true
в конфигурации приложения. Вы также можете настроить время жизни, передав его при вызове метода 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
.