Auth module w Kohana 3 to nic innego jak zbiór bibliotek wymaganych do obsługi autoryzacji użytkowników, lecz to zapewne już wiesz. W tym wpisie przedstawię sposób zastosowania modułu do rejestracji i logowania użytkowników.
Zaczynamy! Pierwszym krokiem jest oczywiście włączenie modułów auth i orm w pliku bootstrap.php (application/bootstrap.php)
Odnajdujemy tablicę z modułami i usuwamy komentarz z początku lini.
'auth' => MODPATH.'auth', 'orm' => MODPATH.'orm',
Tworzenie struktury bazy danych
Zakładam, że skonfigurowałeś już plik konfiguracyjny database.php do obsługi połączeń z MySQLem. Jeśli nie, zrób to czym prędzej.
Ok, teraz musimy poniższy kod struktury tabel użytkowników i ról dodać do naszej bazy (np, z użyciem phpMyAdmin’a).
CREATE TABLE IF NOT EXISTS `roles` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `description` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniq_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `roles` (`id`, `name`, `description`) VALUES(1, 'login', 'Login privileges, granted after account confirmation'); INSERT INTO `roles` (`id`, `name`, `description`) VALUES(2, 'admin', 'Administrative user, has access to everything.'); CREATE TABLE IF NOT EXISTS `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=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `email` varchar(127) NOT NULL, `username` varchar(32) NOT NULL DEFAULT '', `password` char(50) NOT NULL, `logins` int(10) UNSIGNED NOT NULL DEFAULT '0', `last_login` int(10) UNSIGNED, PRIMARY KEY (`id`), UNIQUE KEY `uniq_username` (`username`), UNIQUE KEY `uniq_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `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 `fk_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `roles_users` ADD CONSTRAINT `roles_users_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, ADD CONSTRAINT `roles_users_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE; ALTER TABLE `user_tokens` ADD CONSTRAINT `user_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;
Czym są role użytkowników?
Role to nic innego jak grupy, do których przypisywany jest użytkownik z tabeli users. Za pomocą ról możemy później decydować do jakich zasobów może mieć dostęp dana grupa użytkowników.
Standardową rolą jest rola „login„, która pozwala nam na logowanie. Jeśli chcemy stworzyć administratora musimy dodać go do roli login oraz admin tak by miał dostęp do panelu administracyjnego, ale o tym w przyszłych wpisach.
Kontroler obsługi użytkowników
Przedstawię najprostszy kontroler obsługi użytkowników (register|login|logout).
W tym celu tworzymy plik user.php w folderze application/classes/controller/
Oto jego zawartość:
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_User extends Controller_Template { //dziedziczenie z Controller_Template
var $template; //definiowanie zmiennej do obsługi widoków
public function action_index(){
$this->template = View::factory('user/main'); //załadowanie widoku
$auth = Auth::instance(); //utworzenie instancji obiektu Auth
$whoami $auth->get_user(); //pobieranie danych o zalogowanym użytkowniku
if ($auth->logged_in('login')){ //sprawdzanie czy użytkownik jest zalogowany
//jeśli jest to dopuszczamy (to sekcja dla zalogowanych)
$this->template->wiadomosc = "Witaj $whoami->username!<br />Jesteś zalogowany.";
//i cała reszta kodu dla autoryzowanego użytkownika
}else{ //jeśli nie jest zalogowany, przekierowujemy do logowania
$this->request->redirect('user/login'); //jeśli nie, przekierowujemy do logowania
}
}
public function action_register(){
$this->template = View::factory('user/register'); //załadowanie widoku
$auth = Auth::instance(); //utworzenie instancji obiektu Auth
if ($auth->logged_in('login')){ //sprawdzanie czy użytkownik jest zalogowany
$this->request->redirect('user/login'); //jeśli nie, przekierowujemy do logowania
}else{
if($_POST){ //sprawdzanie czy dane są przesyłane POSTem
$walidacja = new Validate($_POST); //tworzenie obiektu walidacji
$walidacja->rule('login', 'not_empty')
->rule('login', 'alpha_dash')
->rule('email', 'not_empty')
->rule('haslo', 'not_empty')
->rule('email', 'email');
if($walidacja->check()){
$user = ORM::factory('user'); //tworzenie obiektu ORM z użyciem tabeli users
$user->username = $_POST['login']; //przypisanie pola z formularza do nazwy kolumny w tabeli
$user->email = $_POST['email'];
$user->password = $_POST['haslo'];
//instrukcja warunkowa/zapis danych użytkownika/przypisanie roli "login"
if($user->save() && $user->add('roles', ORM::factory('role', array('name' => 'login'))) ){
$this->template->sukces = 'Dziękujemy za rejestrację!'; //przekazanie zmiennej $sukces do widoku
}else{
$this->template->fail = 'Nie udało się dodać użytkownika!'; //przekazanie zmiennej $fail do widoku
}
}else{
$this->template->fail = 'Uzupełnij poprawnie formularz rejestracyjny!';
}
}
}
}
public function action_login(){
$this->template = View::factory('user/login');
$auth = Auth::instance(); //utworzenie instancji obiektu Auth
if ($auth->logged_in('login')){ //sprawdzanie czy użytkownik jest zalogowany
$this->request->redirect('user'); //jeśli jest, przekierowujemy do user
}else{
if($_POST){
$walidacja = new Validate($_POST); //tworzenie obiektu walidacji
$walidacja->rule('login', 'not_empty')
->rule('login', 'alpha_dash')
->rule('haslo', 'not_empty');
if($walidacja->check()){ //jeśli walidacja OK to zaloguj
$auth->login($_POST['login'], $_POST['haslo'], FALSE); //logowanie użytkownika
$this->request->redirect('user'); //przekierowanie po zalogowaniu do kontrolera user
}else{
$this->template->fail = 'Uzupełnij poprawnie formularz!';
}
}
}
}
public function action_logout(){
$this->template = View::factory('user/login');
$auth = Auth::instance(); //utworzenie instancji obiektu Auth
if ($auth->logged_in('login')){ //sprawdzanie czy użytkownik jest zalogowany
if($auth->logout(TRUE)){ //jeśli jest, to go wylogowujemy
$this->template->sukces = 'Pomyślnie wylogowano!';
}else{
$this->request->redirect('user/login'); //przekierowujemy do logowania
}
}else{ //jeśli nie jest zalogowany przekierowujemy do logowania
$this->request->redirect('user/login');
}
}
Uff… piszę to z głowy więc miejmy nadzieję, że wszystko zadziała. Przetestuję to innym razem (jest 03:04). W razie czego czekam na komentarze ;)
Ok kontroler z akcjami już mamy. Jak zauważyliście na początku każdej akcji ładowałem inny widok. Należy teraz stworzyć widoki, które opisałem w komentarzach.
Widoki i Krajobrazy
Widok to niestety nie krajobraz ;) To ogólnie pojęte pliki z kodem (wyglądem) naszej aplikacji. Zgodnie z architekturą danych MVC (Model-View-Controller) należy oddzielać mechanizmy aplikacji od widoku.
Krótka rozpiska, w powyższym kontrolerze użyliśmy następujących widoków, które musimy za chwilę stworzyć.
- application/views/ user/main.php
- application/views/ user/register.php
- application/views/ user/login.php
Przedstawię tylko minimalistyczny obraz jak to wszystko działa, nie będę tworzył nagłówków HTML ani używał, żadnego szablonu CSS.
Oto nasze widoki:
main.php
<?php
if(isset($wiadomosc)){
echo '<h2>'.$wiadomosc.'</h2>';
}
?>
register.php
<?php //wyświetlanie komunikatów, które przekazaliśmy w kontrolerze
if(isset($sukces)){
echo '<h2 style="color:green;">'.$sukces.'</h2>'."\n";
}elseif(isset($fail)){
echo '<h2 style="color:red;">'.$fail.'</h2>'."\n";
}
?>
<?php
echo Form::open()."\n";
?>
<table width="600" border="0" cellpadding="3">
<?php
echo '<tr><td>Nazwa uzytkownika:</td><td>'.Form::input('login').'</td></tr>'."\n";
echo '<tr><td>Hasło:</td><td>'.Form::input('haslo').'</td></tr>'."\n";
echo '<tr><td>Email:</td><td>'.Form::input('email').'</td></tr>'."\n";
echo '<tr><td></td><td>'.Form::submit('rejestruj').'</td></tr>'."\n";
?>
</table>
<?php
echo Form::close()."\n";
?>
login.php
<?php //wyświetlanie komunikatów, które przekazaliśmy w kontrolerze
if(isset($sukces)){
echo '<h2 style="color:green;">'.$sukces.'</h2>'."\n";
}elseif(isset($fail)){
echo '<h2 style="color:red;">'.$fail.'</h2>'."\n";
}
?>
<?php
echo Form::open()."\n";
?>
<table width="600" border="0" cellpadding="3">
<?php
echo '<tr><td>Nazwa uzytkownika:</td><td>'.Form::input('login').'</td></tr>'."\n";
echo '<tr><td>Hasło:</td><td>'.Form::input('haslo').'</td></tr>'."\n";
echo '<tr><td></td><td>'.Form::submit('zaloguj').'</td></tr>'."\n";
?>
</table>
<?php
echo Form::close()."\n";
?>
Jak widać, nie wysiliłem się zbytnio nad widokami ale nie one są tutaj najważniejsze.
Jeśli wszystko zrobiliśmy poprawnie, nasz kontroler powinien działać bez zarzutów. Mile widziane opinie i uwagi do wpisu.
Do rejestracji możemy dopisać potwierdzenie konta przez email, ale o tym w przyszłych wpisach :)
Polecam spis przydatnych metod w KO3









Twitter Updates
Written by sbl
Topics: Framework, Kohana 3, Programowanie