Авторизация

Авторизация пользователей является нередкой задачей при построении приложения. Kohana реализует ее через встроенный модуль Auth. Этот модуль работает по системе «драйверов», вы можете выбрать, каким методом производить авторизацию (по умолчанию Kohana предоставляет файловую авторизацию и драйвер ORM). Помимо этого, возможно написать свой собственный драйвер.

Конфигурация

Файл конфигурации по умолчанию находится в config/auth.php в соответствии со структурой файловой системы. Для настройки доступны следующий параметры:

  • driver — Название драйвера аутентификации, по умолчанию это file.
  • hash_method — Хеш-функция для паролей, по умолчанию это sha256.
  • hash_key — Ключ, используемый при хэшировании пароля, по умолчанию он не указан и рекомендуется установить его в произвольное целое число.
  • session_type — Тип сессии для хранения авторизации пользователя, по умолчанию это стандартная сессия для приложения (Session::$default).
  • session_key — Имя переменной сессии для хранения авторизации пользователя, по умолчанию auth_user.

Базовые действия

Вы можете создать произвольный объект авторизации через стандартный конструктор классов, в этом случае, конструктору нужно передать полностью всю конфигурацию:

$auth = new Auth_ORM(array(
	'hash_method' => 'sha256',
	'hash_key' => 5856739,
	'session_key' => 'custom_auth',
));
$auth2 = new Auth_File(array(
	'hash_method' => 'sha256',
	'hash_key' => 5856739,
	'session_key' => 'custom_auth_2',
));

Таким образом, можно реализовывать несколько одновременных авторизаций. Однако, чаще подразумевается только одна одновременная авторизация, и ее реализуют с помощью конструкции singleton:

$auth = Auth::instance(); // конфигурация в этом случае берется из файла config/auth.php

Эта конструкция доступна из любого места в приложении (будь то контроллер, модель или представление), и рекомендуется использовать именно ее.

Любой драйвер авторизации предоставляет следующие методы:

  • Вход
  • Выход
  • Проверка, совершен ли вход
  • Метод для доступа к данным пользователя

Рассмотрим их подробнее.

Вход

Вход совершается с помощью метода login($username, $password), где $username — имя пользователя и $password — его пароль. Пример совершения авторизации:

$username = 'test';
$password = 'foobar';
if (Auth::instance()->login($username, $password))
{
	// Авторизация прошла успешно
}
else
{
	// Ошибка при авторизации
}

Выход

Выход реализуется с помощью метода logout($destroy), где $destroy — необязательный флаг, при котором уничтожается полностью вся сессия:

Auth::instance()->logout(TRUE);

Проверка на вход

Чтобы проверить, авторизован ли пользователь, можно использовать метод logged_in():

if(Auth::instance()->logged_in())
{
	echo 'Hello, user!';
}

Получение информации

Для получения информации о текущем пользователе доступен метод get_user($default), где $default — необязательный параметр, который будет возвращен, если авторизация не выполнена. Пример:

if(Auth::instance()->logged_in())
{
	$user = Auth::instance()->get_user();
	echo 'Hello, '.$user['username'];
}

Драйвера

Рассмотрим более подробную работу с каждым из драйверов.

File

Для файлового драйвера доступны следующие конфигурационные настройки:

  • users — массив, индексами которого являются имена пользователей, а элементами — их пароли (в хешированном виде).

Авторизация в файловом драйвере происходит именно по массиву users в конфигурационном файле. Поэтому, для файлового драйвера проблематично создать автоматическую регистрацию, смену пароля и изменение профиля. В основном этот драйвер используется для админ-панели, где эти функции не требуются.

Файловый драйвер встроенной авторизации Kohana предоставляет совсем немного расширенных методов, разберем их подробнее:

Принудительный вход

Иногда требуется совершить принудительный вход в систему, без указания пароля. Для этого существует метод force_login($username), где $username — имя пользователя, для которого нужно совершить вход. Пример:

Auth::instance()->force_login('admin');

ORM

На фоне простого файлового драйвера более интересным выглядит драйвер авторизации через ORM. В списке его функциональных возможностей:

  • Возможность регистрации и изменения профиля
  • Система ролей (прав) пользователей
  • Встроенная возможность «бана» пользователей
  • Запоминание авторизации на длительное время

Помимо базовых, для драйвера доступны следующие настройки:

  • lifetime — время, на которое будет запоминаться сессия авторизации (в секундах), по умолчанию это 1209600 (две недели).

При использовании этого драйвера, модуль Auth будет представлять данные пользователя в виде ORM-модели класса Model_User. Соответственно, необходимо подключить сам модуль ORM в файле bootstrap. Код sql для создания таблиц находится в файлах MODPATH/orm/auth-schema-mysql.sql (для MySQL) и MODPATH/orm/auth-schema-postgresql.sql ( для PostgreSQL), необходимо импортировать его в базу данных перед началом использования модуля.

По умолчанию для модели аккаунта предопределены следующие поля:

  • email — электронная почта
  • username — имя пользователя
  • password — хеш пароля
  • logins — количество входов в систему
  • last_login — unix timestamp последнего входа

Вы можете расширить эти поля по собственному усмотрению. Если для этого нужно расширить саму модель, вы можете переопределить ее, наследуя от класса Model_Auth_User:

class Model_User extends Model_Auth_User {
	protected $_table_name = 'custom_user';
}

По умолчанию, модель user содержит связи с моделями user_token и role. Вы можете переопределить и их, наследуя по такому же принципу.

Роли

С помощью этого драйвера возможно каждому пользователю присваивать определенные роли (права), позволяющие разграничивать их по статусу. Например, для пользователя-администратора доступны роли login, edit, delete и read, а обычному пользователю только login и read. Это означает, что обычный пользователь имеет права только входить и читать, а администратор еще и редактировать и удалять.

Реализация происходит через связь ORM «много ко многому» (has many through) в модели user к модели role. Прежде, чем начать работать с ролями, вы должны предопределить их список в базе данных в таблице roles (обычно это делают вручную).

Чтобы проверить, имеет ли пользователь определенную роль, нужно использовать метод logged_in($role), где $role — название или массив названий (name) ролей, либо загруженный объект роли:

if( ! Auth::instance()->logged_in('edit'))
{
	throw new HTTP_Exception_403('Вы не имеете право редактировать запись');
}

Вход

Мы рассматриваем функцию входа снова, потому что она потерпела несколько важных изменений:

  • Вход в систему может производиться как по логину, так и по email одновременно
  • Для метода login доступен третий аргумент $remember, при установлении которого в TRUE авторизационная сессия сохраняется на указанное в настройке lifetime время.
  • Авторизация будет успешной только тогда, когда пользователь имеет роль login.

Пример авторизации с запоминанием сессии:

$email = $_POST['email'];
$password = $_POST['password'];
$remember = isset($_POST['remember']) && $_POST['remember'];
if( ! Auth::instance()->login($email, $password, $remember))
{
	echo 'Невозможно выполнить вход';
}

Запоминание сессии идет с помощью токенов (user_token) — случайно сгенеированных строк, которые одновременно записываются и в cookie и в базу данных. Когда обычная сессия заканчивается, то проверяется наличие той самой cookie с токеном, если он найден, то происходит поиск его в базе, и, если он найден, то происходит автоматический логин.

Выход

Метод выхода содержит еще один аргумент, помимо базового — $logout_all. При установке этого аргумента в TRUE, помимо текущего токена уничтожаются еще и все остальные для этого пользователя.

Пример использования:

Auth::instance()->logout(FALSE, TRUE); // выходим, уничтожаем все токены, но оставляем сессию

Регистрация

Kohana предлагает совершать регистрацию пользователей минуя конструкции ORM с помощью метода create_user($valus, $expected), где $values — массив данных вставляемого пользователя, индексами которого являются названия полей, а элементами — их значения, и опциональный аргумент $expected — массив названий полей, которых нужно извлечь из первого массива. Если второй параметр оставить пустым, то данные будут использованы все.

Пример регистрации:

ORM::factory('user')
	->create_user($_POST, array('username', 'email', 'password'));

В этом случае пользователь будет создан из полей $_POST['username'], $_POST['email'] и $_POST['password'].

Обратите внимание, что после такой регистрации пользователь в базе появится, однако вы не сможете войти через него, т.к. отсутствует роль login. В случае, если вы хотите «активировать» пользователя сразу поле регистрации, полный код будет выглядеть так:

try
{
	$user = ORM::factory('user')
		->create_user($_POST, array('username', 'email', 'password')) // Регистрируем пользователя
		->add('roles', ORM::factory('role', array('name' => 'login')));  // Добавляем роль login
 
	// Регистрация успешна
}
catch(ORM_Validation_Exception $e)
{
	$errors = $e->errors(); 
	// Допущены ошибки при вводе данных
}

Разработка драйверов

Вы можете легко создать свой драйвер, для этого нужно создать наследованный от Auth класс в папке classes/auth. Как минимум, класс должен содержать реализации следующих абстрактных методов:

abstract protected function _login($username, $password, $remember);
abstract public function password($username);
abstract public function check_password($password);

Обычно, требуют доработки и эти методы, поэтому обратите свое внимание и на них:

public function logged_in($role);
public function get_user($default);

После создания, класс драйвера будет иметь имя вида Auth_Example, где example — имя драйвера, которое нужно указывать в конфигурации.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *