Тема где-то баянистая, где-то подробно описанная, но почему-то мне таки пришлось нарабатывать свой опыт и набивать свои шишки. Итак я публикую свой опыт работы с модулем 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;
Вот такое сумбурное у меня знакомство получилось.
Посты по теме:
RSS-подписка
Зачем private-свойства в базовом классе?
@ BIakaVeron:
По замыслу – один раз при создании инициализирую свойства и потом юзаю $this->auth и $this->user во всём контроллере
protected?
@ 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 еснно в исходниках?
change_password()
похоже исключили из последней сборки.
вообще какая то не понятная хрень с этим модулем.
пытаюсь сделать восстановление+смену пароля. хэширую пароль через hash_password($new_pass) сохраняю. и не входит
$new_pass = Text::random(’alnum’ , 8);
$user->password = $this->auth->hash_password($new_pass ) ;
$user->save();
$this->auth->login($user->username ,$new_pass); // выводит 0
$this->user = $this->auth->get_user();