Аутентификация — это процесс проверки подлинности пользователя. Обычно используется идентификатор (например, username или адрес электронной почты) и секретный токен (например, пароль или ключ доступа), чтобы судить о том, что пользователь именно тот, за кого себя выдаёт. Аутентификация является основной функцией формы входа.
Yii предоставляет фреймворк авторизации с различными компонентами, обеспечивающими процесс входа. Для использования этого фреймворка вам нужно проделать следующее:
- Настроить компонент приложения user;
- Создать класс, реализующий интерфейс yiiweb >¶
Компонент user управляет статусом аутентификации пользователя. Он требует, чтобы вы указали identity class, который будет содержать текущую логику аутентификации. В следующей конфигурации приложения, identity class для user задан как appmodelsUser , реализация которого будет объяснена в следующем разделе:
Реализация yiiweb > ¶
identity class должен реализовывать yiiwebIdentityInterface, который содержит следующие методы:
- 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 .
Как объяснялось ранее, вам нужно реализовать только getAuthKey() и validateAuthKey() , если ваше приложение использует только аутентификацию основанную на cookie . В этом случае вы можете использовать следующий код для генерации ключа аутентификации для каждого пользователя и хранения его в таблице user :
Note: Не путайте identity класс User с классом yiiwebUser. Первый является классом, реализующим логику аутентификации пользователя. Он часто реализуется как класс Active Record, связанный с некоторым постоянным хранилищем, где лежит информация о пользователях. Второй — это класс компонента приложения, отвечающий за управление состоянием аутентификации пользователя.
Использование yiiwebUser ¶
В основном класс yiiwebUser используют как компонент приложения user .
Можно получить identity текущего пользователя, используя выражение Yii::$app->user->identity . Оно вернёт экземпляр identity class, представляющий текущего аутентифицированного пользователя, или null , если текущий пользователь не аутентифицирован (например, гость). Следующий код показывает, как получить другую связанную с аутентификацией информацию из yiiwebUser:
Для залогинивания пользователя вы можете использовать следующий код:
Метод yiiwebUser::login() устанавливает identity текущего пользователя в yiiwebUser. Если сессии включены, то identity будет сохраняться в сессии, так что состояние статуса аутентификации будет поддерживаться на всём протяжении сессии. Если включен вход, основанный на cookie (так называемый «запомни меня» вход), то identity также будет сохранена в cookie так, чтобы статус аутентификации пользователя мог быть восстановлен на протяжении всего времени жизни cookie .
Для включения входа, основанного на cookie , вам нужно установить yiiwebUser::$enableAutoLogin в true в конфигурации приложения. Вы также можете настроить время жизни, передав его при вызове метода yiiwebUser::login().
Для выхода пользователя, просто вызовите
Обратите внимание: выход пользователя имеет смысл только если сессии включены. Метод сбрасывает статус аутентификации сразу и из памяти и из сессии. И по умолчанию, будут также уничтожены все сессионные данные пользователя. Если вы хотите сохранить сессионные данные, вы должны вместо этого вызвать Yii::$app->user->logout(false) .
События аутентификации ¶
Класс yiiwebUser вызывает несколько событий во время процессов входа и выхода.
- EVENT_BEFORE_LOGIN: вызывается перед вызовом yiiwebUser::login(). Если обработчик устанавливает свойство isValid объекта в false , процесс входа будет прерван.
- EVENT_AFTER_LOGIN: вызывается после успешного входа.
- EVENT_BEFORE_LOGOUT: вызывается перед вызовом yiiwebUser::logout(). Если обработчик устанавливает свойство isValid объекта в false , процесс выхода будет прерван.
- EVENT_AFTER_LOGOUT: вызывается после успешного выхода.
Вы можете использовать эти события для реализации функции аудита входа, сбора статистики онлайн пользователей. Например, в обработчике для EVENT_AFTER_LOGIN вы можете сделать запись о времени и IP адресе входа в таблицу user .
Page generated on Sun, 17 Nov 2019 19:05:41 +0000
В более-менее крупных проектах большое значение имеет принцип единственной ответственности . В рамках данной статьи — класс сущности (модели) User не должен содержать в себе методы связанные с авторизацией пользователей, этим должен заниматься другой класс. Теперь подробнее.
Откроем класс сущности User (обычно в commonmodels или appmodels ), видим:
класс реализует интерфейс IdentityInterface, а значит содержит в себе методы этого интерфейса:
public static function findIdentity($id)
public static function find >public function getId()
public function getAuthKey()
public function validateAuthKey($authKey)
Данные методы используются при авторизации/идентификации пользователей.
Сам >vendor/yiisoft/yii2/web/IdentityInterface.ph p
В конфигурационных файлах (frontend, backend . ) config/main.php для Yii-2 версии advanced или config/web.php для Yii-2 версии basic указано (по-умолчанию):
видно, что компонент приложения «user» (находится в vendor/yiisoft/yii2/web/User.php ) получает в качестве значения для своего свойства identityClass класс сущности appmodelsUser и использует его методы.
Иногда класс сущности слишком разрастается за счет создания все новых методов, особенно если необходимо создавать дополнительные способы авторизации пользователей, например для API с помощью OAuth.
Поэтому имеет смысл вынести методы касающиеся авторизации в отдельный класс и уже там что-то добавлять/менять, не трогая User.
Поэтому, создаем например в commonauthIdentity.php :
Т.е. переносим сюда указанные выше 5 методов из сущности User. Дополнительно, для доступа к сущности создаем конструктор и методы __get, __call которые позволят получать доступ к свойствам и методам сущности авторизованного пользователя таким образом:
или
Соответственно удаляем эти 5 методов из User и его привязку к интерфейсу:
… implements IdentityInterface
Теперь осталось указать в конфигурации, что используется наш класс Identity вместо сущности User. Для этого во всех конфигах (и фронтенда и бэкенда) поменять
на
Потом везде где встречается вызов
Yii::$app->user->login($user, …)
меняем на
Yii::$app->user->login(new Identity($user), …)
Если вы сохранили стандартную структуру фреймворка по части авторизации, то в таких файлах:
в models/LoginForm.php меняем
на
Для версии advanced так же в SiteController (frontend и backend) в методе actionSignup меняем
на
Таким образом мы вынесли методы связанные с авторизацией пользователей в отдельный класс который теперь можно отдельно расширять и наследовать и разгрузили сущность User.
in my behaviours I have specified that actionList can only be viewed by authenticated users.
In actionList I’m getting the user_id :
All good, but if you go to this action when not logged in, you get an error:
PHP Notice – yiiaseErrorException
Trying to get property of non-object
Makes sense, I’m not logged in so I don’t have a user id, but why does the code go that far? If I comment the $user_ >user->identity->id; out, I get redirected to the login page, which is the expected behaviour. I don’t think I should have to do yet another check to see if someone is logged in in the action itself, shouldn’t that be handled by the behaviours[‘access’] beforehand?