Модуль AUTH в Kohana



kohana Тема где-то баянистая, где-то подробно описанная, но почему-то мне таки пришлось нарабатывать свой опыт и набивать свои шишки. Итак я публикую свой опыт работы с модулем Auth фреймворка Kohana.

Включаем и настраиваем
——————————————–
Сначала нужно включить использование модуля в файле application/bootstrap.php. Кроме модуля auth нам понадобятся модули Database и ORM, так что их тоже нужно включить, если они ещё не включены.

1
2
3
4
5
6
7
8
9
Kohana::modules(array(
	'auth'       => MODPATH.'auth',       // Basic authentication
	// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
	 'database'   => MODPATH.'database',   // Database access
	// 'image'      => MODPATH.'image',      // Image manipulation
	 'orm'        => MODPATH.'orm',        // Object Relationship Mapping
	// 'pagination' => MODPATH.'pagination', // Paging of results
	// 'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	));

Потом заходим в modules/auth/config/auth.php и вносим свои настройки
Перечислю самые интересные настройки:

  • driver – Драйвер данных. Может быть ORM или file. Файловый вариант у меня запустить не получилось. То ли я что-то не так делал, то ли драйвер сырой. Так что используйте ORM :)
  • hash_method – метод хеширования
  • salt_pattern – “шаблон соли”, нечто такое, что невероятно усложняет взлом пароля. Советую изменить дефолтные значения на какие-нибудь свои

База данных
——————————————–
Создадим в нашей базе данных таблицу пользователей

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE `users` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL DEFAULT '',
  `password` char(50) NOT NULL DEFAULT '',
  `email` varchar(127) NOT NULL DEFAULT '',
  `join` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `last_login` int(10) UNSIGNED NOT NULL DEFAULT '0',
  `logins` int(10) UNSIGNED NOT NULL DEFAULT '0',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `uniq_username` (`username`),
  UNIQUE KEY `uniq_email` (`email`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
INSERT INTO `users` (`id`, `username`, `password`, `email`, `join`, `last_login`, `logins`) VALUES
(1, 'admin', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', 'example@example.com', 0, 0, 0);

Поля таблицы думаю в принципе понятны. В поле password будут хранитьcя хитро-солёные хеши пароля.

Кроме пароля и индивидуальных настроек у каждого пользователя может быть своя роль. Типовые роли хранятся в специальной таблице ролей.

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `roles` (
  `id` int(4) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `description` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `uniq_name` (`name`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
INSERT INTO `roles` (`id`, `name`, `description`) VALUES
(1, 'login', 'Разрешён вход в систему.'),
(2, 'admin', 'Пример специфичной роли - Администратор');

Роль login является обязательной и предопределена фреймворком. Она означает возможность заходить на сайт вообще, и должна быть у любого пользователя. Отсутствие его фактически означает бан.

У каждого пользователя может быть несколько ролей. Соответствие ролей и пользователей хранится в отдельной таблице

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `roles_users` (
  `user_id` int(10) UNSIGNED NOT NULL,
  `role_id` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY  (`user_id`,`role_id`),
  KEY `fk_role_id` (`role_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
INSERT INTO `roles_users` (`user_id`, `role_id`) VALUES
(1, 2),
(1, 1);

В этом примере таблицы у пользователя №1 (’admin’) указано две роли №1(’login’) и №2(’admin’).

Для запоминания на сервере сессии пользователя ведётся таблица user_tokens

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `user_tokens` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user_id` int(11) UNSIGNED NOT NULL,
  `user_agent` varchar(40) NOT NULL,
  `token` varchar(32) NOT NULL,
  `created` int(10) UNSIGNED NOT NULL,
  `expires` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `uniq_token` (`token`),
  KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Все таблицы, которые здесь приведены – MyISAM. Если есть желание использовать InnoDB, то можно ещё и внешние ключи подкрутить. Хотя выигрыш от InnoDB наверное не так велик. Таблицы пользователей и доступов довольно консервативны. Впрочем всё должно идти от конкретной цели.

Использование в коде
—————————————-
Использование не очень сложное. В контроллере, который требует авторизации просто нужно использовать Auth::instance(). Чтобы не дёргать инстанс каждый раз, в конструкторе контроллера надо инициализировать некую переменную, например $auth:

1
2
3
4
5
6
7
8
9
10
11
class Controller_Admin extends Controller
{
    protected $auth;
    protected $user;
	public function before() {
		parent::before();
 
		$this->auth = Auth::instance();				
		$this->user = $this->auth->get_user();
 
                    ..........................

В этом примере, мы также завели свойство контроллера $user, используя функцию get_user(). Эта функция извлекает данные о пользователе. Если пользователь не залогинился, то функция возвращает FALSE.

Другие функции auth
———————————

  • login($username, $password, $remember = FALSE) – Собственно функция авторизации. Если авторизация проходит успешно, то возвращает TRUE. Иначе FALSE.

    Параметр $remember аналогичен галочке “Запомнить меня”

  • auto_login() – Попытка автоматического входа. Имеет смысл, если перед этим выполнялся вход с включенной опцией “Запомнить меня”
  • force_login($username) – Принудительный логин без указания пароля. Например, для входа в систему используя секретную ссылку
  • logout($destroy = FALSE) – Выход. Параметр $destroy указывает, стоит ли полностью уничтожать сессию, или достаточно просто разлогиниться, а прочие данные сессии сохранить
  • logged_in($role = NULL) – Функция, которая позволяет проверить, выполнен ли вход. Кроме банального логина может проверять наличие нужной роли.
  • change_password(array & $array, $save = FALSE) – Функция изменения пароля текущего пользователя. Массив $array должен содержать поля ‘password’ и ‘password_confirm’. В случае их несовпадения возвращает FALSE.

    По-умолчанию не сохраняет изменённый пароль. Для сохранения нужно вызвать $user->save(), либо сразу вызывать с парамером $save=TRUE;

Вот такое сумбурное у меня знакомство получилось. :)

Посты по теме:

  1. Kohana. Модуль Image
  2. Kohana для чайников. Настраиваем базу данных
  3. Kohana для чайников. Простейший ORM
  4. Kohana для чайников. Файловая структура, или история одной ошибки.
  5. Kohana. Ускоряем ORM

Категории Kohana |
автор: altesack / Понедельник, Март 01, 2010 / 18 комментов »

18 комментов

    Зачем private-свойства в базовом классе?

    @ BIakaVeron:
    По замыслу – один раз при создании инициализирую свойства и потом юзаю $this->auth и $this->user во всём контроллере

    @ BIakaVeron:
    Ах да. Этот класс у меня не базовый. Я у себя его не наследую. В таком контексте оно не важно. Пожалуй исправлю

    ИМХО, private имеет смысл использовать только когда явно надо закрыть доступ потомкам, в остальных случаях – protected. Даже если Вы сейчас не планируете наследование, оно может пригодиться позже (может даже не Вам)

    @ BIakaVeron:
    Согласен. Fixed

    Что то сложновато все с этой Kohana.
    Пожылуй из за таких сложностей все и бегут на тот же WP или какой другой движок для сайта.

    @ Andrey:
    Это не готовая система для сайта, это фреймворк – т.е. кирпичи для построения движка для сайта. и Auth – просто один из кирпичиков.

    а помоему всё достаточно просто по сравнению с другими фреймворками. да и сравнивать цмс с фреймворком это как сравнивать масло и маргарин

    Евгений пишет:

    а помоему всё достаточно просто по сравнению с другими фреймворками. да и сравнивать цмс с фреймворком это как сравнивать масло и маргарин

    Скорее всего как масло с с молоком, из которого делается масло :)

    «Использование не очень сложное. В контроллере, который требует авторизации просто нужно использовать Auth::instance(). Чтобы не дёргать инстанс каждый раз, в конструкторе контроллера надо инициализировать некую переменную, например $auth»

    Если заглянуть в код метода Auth::instance:

    public static function instance()
    {
    if ( ! isset(Auth::$_instance))
    {
    // Load the configuration for this type
    $config = Kohana::config(’auth’);
    if ( ! $type = $config->get(’driver’))
    {
    $type = ‘ORM’;
    }

    // Set the session class name
    $class = ‘Auth_’.ucfirst($type);

    // Create a new session instance
    Auth::$_instance = new $class($config);
    }

    return Auth::$_instance;
    }

    то мы увидим, что в Kohana кешируются все инстансы. Незачем создавать дополнительные переменные ))

    @ Дмитрий:
    здесь, наверное, автор имел ввиду не “дёргать” а писать каждый раз Auth::instance() или Auth::$_instance

    “Потом заходим в modules/auth/config/auth.php и вносим свои настройки”

    Другие модули менять не стоит, я думаю будет лучше скопировать файл с конфигом в APPPATH.”config” и уже там править как хочется. Тогда при обновлении данного модуля, проблем не будет.

    подскажи, как получить данные об авторизованном пользователе после проверки logged_in? например мне нужны его id и логин. как я понял работать нужно через get_user, но как дальше обработать полученный результат?

    вот пример из статьи:

    $this->auth = Auth::instance();
    $this->user = $this->auth->get_user();

    как из $this->user вытащит id и login ?

    get_user() возвращает фактически ORM модель. Так что можно вытащить любое поле из таблицы users

    Например
    $this->user->username
    $this->user->id

    и т.д.

    Если иногда непонятна суть получаемых структур – просто выводите
    Kohana::debug($this->user)

    спасибо, все работает!

    А есть статьи про то как осуществить регистрацию пользователя и вообще есть ли примеры простых блогов/сайтов с авторизацией на Auth еснно в исходниках?

Ответить