RkBlog

Hardware, programming and astronomy tutorials and reviews.

Prosty Blog - Logowanie do Panelu Admin

Musimy stworzyć teraz prosty mechanizm logowania dla admina.

Panel Admina jest praktycznie gotowy, brakuje jednak kluczowej opcji - ograniczenia dostępu. Musimy stworzyć prosty mechanizm logowania dla admina. Jako że CI zabija również tablicę $_SERVER nie możemy skorzystać z autoryzacji HTTP (z którą i tak są kłopoty na niektórych serwerach). Skorzystamy z ciasteczek.
Do kontrolera Admin dodajemy metody:
<?php
function _check_login()
 {
 IF($cookie = $this->input->cookie('cicookie', True))
       {
       IF($cookie == md5(sha1($this->login.$this->password.$this->input->ip_address())))
        {
        return true;
        }
       else
        {
        return false;
        }
       }
 else
       {
       return false;
       }
 }
function login()
 {
 $data["login"] = array('name' => 'login');
 $data['pass'] = array('name' => 'pass');
 
 $rules['login'] = "required|max_length[100]|xss_clean";
 $rules['pass'] = "required|max_length[100]|xss_clean";
 $this->validation->set_rules($rules);
 
 if ($this->validation->run() == FALSE)
       {
       $data['login']['value'] = $this->input->post('login');
       $data['pass']['value'] = $this->input->post('pass');
       $this->response['content'] = $this->load->view('login', $data, True);
       }
 else
       {
       IF(md5(sha1($this->login.$this->password.$this->input->ip_address())) == md5(sha1($this->input->post('login').$this->input->post('pass').$this->input->ip_address())))
        {
        setcookie("cicookie", md5(sha1($this->login.$this->password.$this->input->ip_address())), time()+172800, '/', '', '0');
        $this->response['content'] = '<h1>Zalogowany</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('admin').'">';
        }
       else
        {
        $this->response['content'] = '<h1>Błąd logowania</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('admin').'">';
        }
       }
 $this->load->view('index', $this->response);
 }
function logout()
 {
 setcookie("cicookie", NULL, time()-172800, '/', '', '0');
 header('Location: '.site_url('admin'));
 }
Konstruktor modyfikujemy do postaci:
<?php
function Admin()
 {
 parent::Controller();
 $this->response = array();
 $this->password = 'Rychu13';
 $this->login = 'Rysiek';
 IF(!Admin::_check_login() and $this->uri->segment(2) != 'login')
       {
       header('Location: '.site_url('admin/login'));
       }
 }
Metoda _check_login() jest metodą "prywatną" (niedostępną poprzez URI) i sprawdza czy jesteśmy zalogowani. System opiera się na założeniu że:
- Stosujemy ciasteczko o nazwie "cicookie"
- Ciacho zawiera pewną daną określającą że admin to admin
- Dokładniej ciasteczko zawiera hasz z trzech zmiennych:
md5(sha1($this->input->post('login').$this->input->post('pass').$this->input->ip_address())
- loginu, hasła i adresu IP
- Hasz generowany przez md5 i sha1 to nieodkodowywalny łańcuch.
- Metoda _check_login() porównuje hasz z ciasteczka z haszem otrzymanym z ustawionego loginu, hasła i bierzącego IP: jeżeli są takie same to jesteśmy "zalogowani"
Powyższy "system" logowania jest dość słaby. Chcąc stworzyć taki system z prawdziwego zdarzenia trzeba skorzystać z bazy danych i zapisywać np. znacznik czasu (time()) logowania oraz umieszczać je również w ciachu wewnątrz jakiegoś hasza, tak by przechwycenie ciasteczka przez inną osobę nic nie dało ("włamywacz" może "zmienić" swoje IP).
Metoda login() to formularz z walidacją i utworzeniem ciacha jeżeli hasz danych z formularza zgadza się z haszem danych ustawionych w konstruktorze. Metoda logout() wylogowuje. Szablon logowania:
<h1>Logowanie</h1>
<center><?=$this->validation->error_string; ?></center>

<?php echo form_open('admin/login'); ?>
<table width="90%" border="0" cellspacing="3" cellpadding="3">
<tr><td width="180"><B>Login</B></td><td><?php echo form_input($login); ?></td></tr>
<tr><td width="180"><B>Hasło</B></td><td><?php echo form_password($pass); ?></td></tr>
<tr><td> </td><td><?php echo form_submit('submit', 'Zapisz'); ?></td></tr>
</table>
<?php echo form_close(); ?>

<div class="rule"></div>
W konstruktorze mamy $this->password i $this->login określające login i hasło. Następnie mamy:
IF(!Admin::_check_login() and $this->uri->segment(2) != 'login')
NazwaKlasy::metoda wywoła tą metodę wewnątrz klasy we wskazanym miejscu. Tutaj sprawdzamy zalogowanie. Jeżeli nie jesteśmy zalogowani i nie jesteśmy już na stronie logowania to przenoszeni jesteśmy na ową stronę logowania. Nie dostaniemy się na żadną stronę zależną od tego kontrolera bez zalogowania. Panel Admina zabezpieczony.
W widoku index.php obok linku "Główna" dodałem taki kod:
<?php

<?PHP
IF ($this->uri->segment(1) == 'admin' and $this->uri->segment(2) != 'login')
 {
 echo ' <li><a href="'.site_url('admin/logout').'" title="home">Wyloguj</a></li>';
 }
?>
Jeżeli jesteśmy w panelu admina (/admin/*) i nie na stronie logowania to wyświetli się link "Wyloguj", który nas wyloguje i przeniesie na stronę logowania.
RkBlog

14 July 2008;

Comment article