Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Logowanie
Forum PHP.pl > Forum > PHP
Maveral
Hej, napisałem sobie taki mały skrypcik do logowania, a jako że nie tworzyłem dotychczas niczego podobnego, to potrzebuję Waszej porady odnośnie zabezpieczeń i nie tylko. Całość wygląda tak:

logowanie.cls
Kod
<?php

class logowanie
{
    private $login;
    private $haslo;
    
    function __construct($login, $haslo)
    {
        $this -> login = $login;
        $this -> haslo = $haslo;
    }
    
    public function sprawdz()
    {
        if ($this -> login && $this -> haslo) {
    
            if ($this -> login == "jan" && $this -> haslo == "jan")
            {
                session_id();
                $_SESSION[$user] = $this -> login;
                echo "Jestes zalogowany jako <b>" .$_SESSION[$user]. "</b> o id = " .session_id(). " - <a href=log2.php>przejdz dalej</a>";
            }        
            else
            {
                echo "Nieprawidlowy login lub haslo";
                echo "</BR></BR>";
                $formularz = new form_logowania();
                $formularz -> wyswietl();
            }
        
        }
    
        else if (session_id() && $_SESSION[$user])
        {
            echo "Jestes zalogowany jako <b>" .$_SESSION[$user]. "</b> o id = " .session_id(). " - <a href=log2.php>przejdz dalej</a>";
        }
    
        else
        {
            $formularz = new form_logowania();
            $formularz -> wyswietl();
        }
    
    }    
}
    
?>


Klasa form_logowania() wstawia po prostu formularz do zalogowania. Login i hasło będzie pobierane oczywiście z bazy danych. Tutaj dane są przykładowe i "na szybkiego" smile.gif Aha, i wyświetlanie session_id(), to tylko tak dla mnie, żebym widział, że się wygenerowało.

Kod powyżej wstawiam tak:

log.php
Kod
<?php
session_start();

function __autoload($nazwa_klasy) {
    require_once("klasy/$nazwa_klasy.cls");
}

$logowanie = new logowanie($_POST['login'], $_POST['haslo']);
$logowanie -> sprawdz();

?>


I przykładowa strona, która przejmuje id sesji oraz nazwę użytkownika:

log2.php
Kod
<?php
session_start();

if (session_id() && $_SESSION[$user]) {
echo "Jestes zalogowany jako <b>" .$_SESSION[$user]. "</b> o id = " .session_id(). " - <a href=log.php>przejdz wstecz</a>";
}
else
{
echo "Nie ma cie w bazie - <a href=log.php>Wroc do strony logowania</a></BR>";
}

?>


Teraz mam pytania.
1. Czy do super globalnej tablicy $_SESSION mogę wrzucic co mi się podoba?
2. Czy przekazywanie przez tę tablicę loginu jest ok, czy lepiej to zrobic jakoś inaczej?
3. Czy dobrze rozumiem, że ta tablica jest przechowywana w ciastkach?
4. Czy zamiast pisać:
Kod
$logowanie = new logowanie($_POST['login'], $_POST['haslo']);
$logowanie -> sprawdz();

...można napisać bez tej zmiennej? Chodzi o coś w stylu:
Kod
new logowanie($_POST['login'], $_POST['haslo']) -> sprawdz();

Jeśli tak, to jak, bo u mnie na localhoście nie działa? (wiem, że to pytanie powinno być w dziale o OOP, ale zamiast się rozdrabniać, napiszę w jednym poście)
5. Czy skrypt jest dość bezpieczny jak na zwykłą szkolną stronkę? Jeśli jest dziurawy jak sito, to proszę Was o podanie mi ewentualnych możliwości odnośnie wykradzenia sesji, przejęcia hasła oraz loginu itp.

Pozdrawiam.
Quider
Po pierwsze ELSEIF sie pisze chyba razem:)
Po drugie, ja w Twojej funkcji sprawdzałbym czy istnieje taki id użytkownika, dopiero potem przesłał z bazy danych sobie login i to co jest potrzebne. Chyba, że login jest tajny np jak w banku to działasz tylko na ID.

Po trzecie, spróbuj to zrobić na jakimś frameworku, pójdzie szybciej i jest sprawdzone pod względem dziur. Choć wiem, że napisanie swojego frameworka to większa frajda ;p
kallosz
Cytat(Quider @ 30.05.2009, 10:39:15 ) *
Po pierwsze ELSEIF sie pisze chyba razem:)
nie ma to znaczenia.

jak mu wygodniej.
Maveral
Cytat("Quider")
Po drugie, ja w Twojej funkcji sprawdzałbym czy istnieje taki id użytkownika, dopiero potem przesłał z bazy danych sobie login i to co jest potrzebne. Chyba, że login jest tajny np jak w banku to działasz tylko na ID.

Po trzecie, spróbuj to zrobić na jakimś frameworku, pójdzie szybciej i jest sprawdzone pod względem dziur. Choć wiem, że napisanie swojego frameworka to większa frajda ;p

Jeśli chodzi o sprawdzenie najpierw id, to w zasadzie muszę to przemyśleć, ale wydaje sie to być dobrym pomysłem. Co do frameworka, to jednak na tym mi nie zależy, gdyż chcialbym się przy okazji sam tego nauczyć. Korzystanie z gotowców, to dla mnie ostateczność - takie zboczenie winksmiley.jpg

Edit: Jesli chodzi o tablicę SESSION, to już dowiedzialem się, że mogę sobie tam wrzucać co chcę winksmiley.jpg

EDIT:

Tak się zastanawiam dlaczego na localhoście ten skrypt wywala mi błędy:

logowanie.cls
  1. <?php
  2.  
  3. class logowanie
  4. {
  5.    private $login;
  6.    private $haslo;
  7.    
  8.    function __construct($login, $haslo)
  9.    {
  10.        $this -> login = $login;
  11.        $this -> haslo = $haslo;
  12.    }
  13.    
  14.    public function sprawdz()
  15.    {
  16.        if ($this -> login && $this -> haslo) {
  17.        
  18.            //łączymy się z bazą danych
  19.            $baza_conn = new baza_conn();
  20.            $baza_conn -> polacz();
  21.  
  22.            // wybieramy dane z naszej tabeli
  23.            $zapytanie = "SELECT login, haslo FROM loginy WHERE login = '" .$this -> login. "' AND haslo = '" .md5($this -> haslo). "'";
  24.            $idzapytania = mysql_query($zapytanie);
  25.            
  26.            //do zmiennej wrzucamy ilość wierszy jaką zwróciło zapytanie do bazy
  27.            $czy_jest = mysql_num_rows($idzapytania);
  28.            
  29.            // zamykamy połączenie
  30.            mysql_close($connection);
  31.            
  32.                //sprawdzamy czy ilość wierszy wyrzuconych przez zapytanie =0 czy >0. Jeśli 0, to logowanie da FALSE.
  33.                if ($czy_jest == 0)
  34.                {
  35.                    echo "Niepoprawny login lub haslo";
  36.                    echo "</BR></BR>";
  37.                    $logowanie = new form_logowania();
  38.                    $logowanie -> wyswietl();
  39.                }
  40.                else
  41.                {
  42.                    session_regenerate_id(); //przy każdym logowaniu zmienia klucz sesji. Zwraca 1 jeśli funkcja zmieniła klucz, a 0 jeśli nie.
  43.                    $_SESSION['id'] = session_id(); //zapisujemy generowany klucz do zmiennej.
  44.                    $_SESSION['user'] = $this -> login;
  45.                    echo "Jestes zalogowany jako <b>" .$_SESSION['user']. " - <a href=log2.php>przejdz dalej</a> lub <a href=log.php?wyloguj=1>wyloguj sie";
  46.                }    
  47.        }
  48.        
  49.        //Jeśli przejmujemy zmienną "wyloguj" z parametrem "1" i gdy user jest zalogowany, to wylogowujemy go. Niszczymy sesję i robimy przekierowanie na stronę logowania.
  50.        else if ($_GET['wyloguj']==1 && $_SESSION['user'] && $_SESSION['id'])
  51.        {
  52.            session_unset();
  53.            session_destroy();
  54.            header('Location: log.php');    
  55.        }
  56.        
  57.        //Jeśli user jest już zalogowany, to wywalamy mu komunikat :)
  58.        else if ($_SESSION['id'] && $_SESSION['user'])
  59.        {
  60.            echo "Jestes zalogowany jako <b>" .$_SESSION['user']. "</b> o id = " .$_SESSION['id']. " - <a href=log2.php>przejdz dalej</a> lub <a href=log.php?wyloguj=1>wyloguj sie";
  61.        }
  62.        
  63.        //Jeśli to pierwsze wywołanie tej strony, bez żadnych parametrów, to wyświetlamy formularz logowania.
  64.        else
  65.        {
  66.            $logowanie = new form_logowania();
  67.            $logowanie -> wyswietl();
  68.        }
  69.    
  70.    }    
  71. }
  72.  
  73.  
  74. ?>


Wyskakuje coś takiego:

Cytat
Warning: mysql_close(): supplied argument is not a valid MySQL-Link resource in F:\Program Files\WebServ\httpd-users\mariusz\klasy\logowanie.cls on line 30

Warning: session_regenerate_id() [function.session-regenerate-id]: Cannot regenerate session id - headers already sent in F:\Program Files\WebServ\httpd-users\mariusz\klasy\logowanie.cls on line 42
Jestes zalogowany jako xxx o id = a59b870d13c9ae885c77a9cf4a494b32 - przejdz dalej lub wyloguj sie


1. Dziwne, że ten sam skrypt działa np. TUTAJ i nie wyrzuca mi żadnych błędów (login: zmija, hasło: zmija). Jeśli chodzi o localhost, to zmieniłem jedynie dane do połączenia z bazą, żeby działało na localu. Reszta kodu bez zmian.
2. Jeżeli chodzi o drugi komunikat, to przeczytałem to co pisze TUTAJ i działa tylko z ob_start() i ob_end_flush(). Zmiana output_buffering na "On" w php.ini nic nie dała.
3. Co do błędu pierwszego, to już w ogóle pojęcia nie mam o co chodzi.

Wie ktoś co może być przyczyną?
golaod
Przestań zawracać ludziom głowy i popatrz na swój własny kod.
  1. <?php
  2. $baza_conn = new baza_conn();
  3. $baza_conn -> polacz();
  4.  
  5. // wybieramy dane z naszej tabeli
  6. $zapytanie = "SELECT login, haslo FROM loginy WHERE login = '" .$this -> login. "' AND haslo = '" .md5($this -> haslo). "'";
  7. $idzapytania = mysql_query($zapytanie);
  8.          
  9. //do zmiennej wrzucamy ilość wierszy jaką zwróciło zapytanie do bazy
  10. $czy_jest = mysql_num_rows($idzapytania);
  11.          
  12. // zamykamy połączenie
  13. mysql_close($connection);
  14. ?>

A drugi błąd wynika z pierwszego.
gcdreak
Nie zapominaj o przefiltrowaniu danych pochądzących z formularzy.
Jak wysyłasz coś do bazy danych to zastosuj funkcję addslashes() lub mysql_real_escape_string() (może ktoś podpowie której z tych funkcji powinno się używać?).
Jeśli używasz addslashes() to należy pamiętać, aby po pobraniu danych z bazy zastosować funkcje stripslashes().
Nie możesz polegać na mechaniźmie magic_quotes_gpc ponieważ będzie on wycofany z PHP 6!
Maveral
Cytat(golaod @ 10.06.2009, 13:15:13 ) *
Przestań zawracać ludziom głowy i popatrz na swój własny kod.

Dzięki za naprowadzenie, poradziłem już sobie. Czasem człowiek robi głupie błędy... ale to nie znaczy, że masz się do niego zwracać w ten sposób. Moża było posta napisać bez tej głupiej docinki.

@gcdreak: Dzięki za podpowiedź, choć o filtrowaniu już myślałem wcześniej smile.gif Podłączam się do twojego pytania - addslashes() czy mysql_real_escape_string()?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.