Авторизация
Авторизация — это процесс проверки личности пользователя. Обычно она использует идентификатор (например, имя пользователя или адрес электронной почты) и секретный токен (например, пароль или токен доступа), чтобы определить, является ли пользователь тем, за кого себя выдаёт. Авторизация является основой функции входа в систему.
Yii предоставляет фреймворк авторизации, который связывает различные компоненты для поддержки входа в систему. Для использования этого фреймворка, вам, в основном, нужно выполнить следующие действия:
- Настроить компонент приложения user;
- Создать класс, реализующий интерфейс yii\web\IdentityInterface.
Настройка yii\web\User
Компонент приложения user управляет состоянием авторизации пользователя. Он требует указать класс сущности, содержащий фактический логику авторизации. В следующей конфигурации приложения класс сущности для user настроен на app\models\User, реализация которого поясняется в следующем подразделе:
return [
'components' => [
'user' => [
'identityClass' => 'app\models\User',
],
],
];
Реализация yii\web\IdentityInterface
Класс сущности должен реализовывать интерфейс yii\web\IdentityInterface, который содержит следующие методы:
- findIdentity(): ищет экземпляр класса сущности с заданным идентификатором пользователя. Этот метод используется, когда необходимо сохранять состояние входа в систему через сессию.
- findIdentityByAccessToken(): ищет экземпляр класса сущности по указанному токену доступа. Этот метод используется при аутентификации пользователя по отдельному секретному токену (например, в бессерверном REST-приложении).
- getId(): возвращает идентификатор пользователя, представленного этим экземпляром сущности.
- getAuthKey(): возвращает ключ, используемый для проверки входа в систему на основе cookie. Ключ хранится в cookie входа в систему и позже сравнивается с серверной версией, чтобы убедиться в валидности cookie входа в систему.
- validateAuthKey(): реализует логику проверки ключа входа в систему на основе cookie.
Если какой-либо метод не нужен, его можно реализовать с пустым телом. Например, если ваше приложение — чисто бессерверное REST-приложение, вам нужно будет реализовать только 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;
}
}
Примечание: Не путайте класс
Userсущности с yii\web\User. Первый — это класс, реализующий логику авторизации. Он часто реализуется как класс Active Record, связанный с каким-либо постоянным хранилищем для хранения данных учетных данных пользователя. Последний — это класс компонента приложения, ответственный за управление состоянием авторизации пользователя.
Использование yii\web\User
Вы в основном используете yii\web\User в качестве компонента приложения 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 на 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.
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-security-authentication.html