Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Logowanie i sesja
uirapuru
post
Post #1





Grupa: Zarejestrowani
Postów: 182
Pomógł: 9
Dołączył: 30.04.2005

Ostrzeżenie: (0%)
-----


Takie szybkie pytanie, jak ogólnikowo wygląda model logowania i obsługi sesji w Waszych projektach? Czy może jest jakiś uniwersalny dobry sposób robienia tego? Przyznam, że zrobiłem sam, działa, ale nie wiem na ile jest włamoodporne i może znalazłoby sie lepsze rozwiązanie.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
wNogachSpisz
post
Post #2





Grupa: Zarejestrowani
Postów: 1 233
Pomógł: 87
Dołączył: 6.03.2009

Ostrzeżenie: (40%)
XX---


Korzystam z frameworka CodeIgniter, tam sesja jest zaimplementowana i dostepna dla kodującego w bardzo przyzwoitym abstrakcyjnym layerze

* szyfrowanie sesji
* flashdata (taki var w sesji ktory znika po kolejnym przeladowniu strony, dobre do obslugi komunikatow)

Nie ukrywam ze szyfrowanie sesji daje duze mozliwosci mozna sie szarpnac na  przechowywaniem w cookie wartosci logged_as=>admin
juz nie trzeba sprawdzac SID'a w bazie czy gdziekolwiek indziej, a to moze szalenie pozytywnie wplynac na wydajnosc ;p i u mnie wplywa ;p
Go to the top of the page
+Quote Post
pgrzelka
post
Post #3





Grupa: Zarejestrowani
Postów: 313
Pomógł: 24
Dołączył: 9.08.2008
Skąd: Kielce

Ostrzeżenie: (0%)
-----


pokaż kod to powiemy czy skrypt jest bezpieczny
Go to the top of the page
+Quote Post
uirapuru
post
Post #4





Grupa: Zarejestrowani
Postów: 182
Pomógł: 9
Dołączył: 30.04.2005

Ostrzeżenie: (0%)
-----


Nie wiem czy będzie chciało się komuś analizować kod, ale podaję jego najważniejsze części. Generalnie wymyśliłem to sobie tak, że wspolpracuja ze soba trzy glowne obiekty (przy czym nie mam zielonego pojecia o programowaniu obiektowym jeszcze, wiec wybaczcie bledy i chetnie poczytam wskazowki)

Sesja() - jest warstwa pomiedzy sesją a skryptem, generalnie settery i gettery, sprawdzanie czy sesja istnieje i czy klient jest zalogowany
Profil() - info o uzytkowniku (nazwiska, zdjecia itp)
User() - haslo, nazwa, mail
Mainframe() - taki niby obiekt, a wlasciwie to plik index odwoluje sie tylko do jego metod a on "rozporządza" akcjami

TabProfiles(), TabUsers() - warstwa pomiedzy skryptem a bazą (potomne klasy Mysql, ktora nawiazuje i konczy polaczenie) - maja metody zawierajace bezposrednie query do bazy, a takze metody ktore mi troche ulatwiaja prace (np. GetProfileIDfromUserID() itd)

No wiec po kolei, bede wklejac kluczowe fragmenty:

plik index.php:

  1. <?php
  2. switch($akcja[1]) {
  3.    case "reg":
  4.        if($_POST["akcja"]=="reg")
  5.        {
  6.            if($mainframe->rejestracja($_POST)) { header("location: /"); }
  7.        }
  8.        else
  9.        {
  10.            header("location: /login");
  11.        }
  12.        break;
  13.    case "login":
  14.        if(isset($_POST["akcja"]) && $_POST["akcja"]=="login") {
  15.            if($mainframe->logowanie($_POST)) { header("location: /"); }
  16.        }
  17.        else
  18.        {
  19.            echo MAIN_HTML_HEAD;
  20.            $form->menu();
  21.            $form->logowanie();
  22.            $form->rejestracja();
  23.        }
  24.        break;
  25.    case "logout":
  26.        $mainframe->wylogowanie();
  27.        header("location: /");
  28.        break;
  29.    case "profil":
  30.        if(!$sesja->get("loggedin"))
  31.        { // jeśli nie zalogowany przekierowuje na strone logowania
  32.            header("location: /login");
  33.            break;
  34.        }
  35.        if(isset($_POST["akcja"]) && $_POST["akcja"]=="profile")
  36.        { // jesli zalogowany i nastapilo wyslanie formularza wykonuje akcje
  37.            $mainframe->profil_edit($_POST,$_FILES);
  38.            header("location: /profil");
  39.        }
  40.        else
  41.        { // w innym wypadku pokazuje jedynie formularz do edycji profilu
  42.            echo MAIN_HTML_HEAD;
  43.            $mainframe->profil_view();
  44.        }
  45.        break;
  46.    case "start":
  47.                // pokazuje pierwsza strone
  48.        echo MAIN_HTML_HEAD;
  49.        $form->menu();
  50.        echo "Witaj na stronie głównej!";
  51.        break;
  52.        
  53.    default:
  54.        header("location: /start");
  55.        echo MAIN_HTML_HEAD;
  56. }
  57. ?>


to może teraz include z mainframe()

  1. <?php
  2. class Mainframe
  3. {
  4.    function __construct()
  5.    {
  6.        $profil = Profil::getInstance();
  7.        $this->tab_profiles = new TabProfiles();
  8.    }
  9.  
  10.    function rejestracja($post)
  11.    {
  12.        $post=tablica_zabezpiecz($post);
  13.        $user = new Uzytkownik();
  14.        $user->setNazwa($post["username"]);
  15.        $user->setHaslo($post["password1"], $post["password2"]);
  16.        $user->setEmail($post["email"]);
  17.        if(!$user->zarejestruj()) { echo "Błąd podczas przesyłania danych do rejestracji!"; return false;}
  18.        return true;
  19.    }
  20.    function logowanie($post)
  21.    {
  22.        $post=tablica_zabezpiecz($post);
  23.        $user = new Uzytkownik();
  24.        if(!$user->loginUser($post["username"],$post["password"])) { echo "Błąd podczas logowania!"; return false; }
  25.        return true;
  26.    }
  27.    function wylogowanie()
  28.    {
  29.        Uzytkownik::logout();
  30.    }
  31.    function profil_view()
  32.    {
  33.        $profil = Profil::getInstance();
  34.        
  35.        $menu=new Form();
  36.        $menu->menu();
  37.        
  38.        $dane=tablica_odbezpiecz($profil->data);
  39.        
  40.        $form_profil = new Form();
  41.        $form_profil->setAction("/profil");
  42.        $form_profil->profil($dane);    //podstawianie pod profil i wywalanie formularza do edycji
  43.        
  44.        $form_foto = new Form();
  45.        $form_foto->setAction("/profil");
  46.        echo $form_foto->foto_user($dane);    //podstawianie pod profil i wywalanie formularza do edycji
  47.        
  48.    }
  49.    function profil_edit($post,$file)
  50.    {
  51.            $profil = Profil::getInstance();
  52.            $avatar = $profil->data["avatar"];
  53.            $zdjecie = $profil->data["zdjecie"];
  54.            switch($post["opcja"]) {
  55.                case "foto":
  56.                    $odp = $profil->load_files($file);
  57.                    
  58.                    if($odp[0] != false && $post["usun_avatar"] != "on")
  59.                    {
  60.                        $profil->data["avatar"] = $odp[0];
  61.                    }
  62.                    else if($post["usun_avatar"] == "on")
  63.                    {
  64.                        unlink($GLOBALS["imagedir_users"].$profil->data["avatar"]);
  65.                        $profil->data["avatar"] = false;
  66.                    }
  67.                    if($odp[1] != false && $post["usun_zdjecie"] != "on")
  68.                    {
  69.                        $profil->data["zdjecie"] =  $odp[1];
  70.                    }
  71.                    else if($post["usun_zdjecie"] == "on")
  72.                    {
  73.                        unlink($GLOBALS["imagedir_users"].$profil->data["zdjecie"]);
  74.                        $profil->data["zdjecie"] = false;
  75.                    }
  76.                    break;
  77.                case "zapisz":
  78.                    $profil->data = tablica_zabezpiecz($post);
  79.                    
  80.                    $profil->data["avatar"] = $avatar;
  81.                    $profil->data["zdjecie"] =  $zdjecie;
  82.                    break;
  83.            }
  84.            $profil->reload_sesja($profil);
  85.            $profil->zapisz();            
  86.    }    
  87. }
  88. ?>


tutaj czesc profil, konstruktor, sprawdza zalogowanie i dane w sesji przed powstaniem

  1. <?php
  2. class Profil
  3. {
  4.    public $profile_id="-1";
  5.    public $user_id="-1";
  6.    public $data=Array("");
  7.    
  8.    private static $instance;
  9.    private function __clone(){} //Uniemozliwia utworzenie kopii obiektu
  10.  
  11.    public static function getInstance ()
  12.    {
  13.        if (self::$instance === null) {
  14.            self::$instance = new self();
  15.        }
  16.        return self::$instance;
  17.    }
  18.    
  19.    private function __construct()
  20.    {
  21.        $sesja = Sesja::getInstance();
  22.        if(!$sesja->get("loggedin"))
  23.        {
  24.            $this->destroyer();
  25.            return false;
  26.        }
  27.        
  28.        $this->user_id = $sesja->get("id");
  29.        $this->profile_id = $this->getProfileIdFromUserID($sesja->get("id"));
  30.        
  31.        if(!$this->testProfil())
  32.        {
  33.            $this->data=Array();
  34.            $this->zapisz();
  35.        }
  36.        else
  37.        {
  38.            // na tej lekcji zrozumieliśmy, że lepiej trzymać data w sesji, niż za każdym razem odwoływać się do bazy (będzie mucho rapido)
  39.            if(!$sesja->get("profile_data"))
  40.            {
  41.                $sesja->set("profile_data",$this->dumpData());
  42.            }
  43.            $this->data = $sesja->get("profile_data");
  44.        }
  45.    }
  46.  
  47.    function dumpData()
  48.    {
  49.        $sesja=Sesja::getInstance();
  50.        $tabusers=TabUsers::getInstance();
  51.        
  52.        if(!$sesja->get("profile_data"))
  53.            {
  54.                $tab_profiles = TabProfiles::getInstance();
  55.                $this->data = TabProfiles::getAllData($this->profile_id); // zwraca false, jeśli nie ma profilu!
  56.                if(!$this->data)
  57.                {
  58.                    return false;
  59.                }
  60.                
  61.                $this->data["username"]=Sesja::get("name");
  62.                $this->data["email"]=$tabusers->getEmail(Sesja::get("name"));
  63.                $this->reload_sesja($this);
  64.            }
  65.        return $sesja->get("profile_data");
  66.    }
  67.    function reload_sesja(Profil $obj) // ta funkcja odczytuje aktualne dane z obiektu profil i zapisuje je do sesji
  68.    {
  69.        $sesja = Sesja::getInstance();
  70.        $sesja->set("profile_data", $obj->data);
  71.    }
  72. ?>


no i sama klasa sesja()

  1. <?php
  2. class Sesja
  3. {
  4.    public $id="-1";
  5.    public $profile_data;
  6.    
  7.    private static $instance;
  8.    private function __clone(){} //Uniemozliwia utworzenie kopii obiektu
  9.  
  10.    public static function getInstance ()
  11.    {
  12.        if (self::$instance === null) {
  13.            self::$instance = new self();
  14.        }
  15.        return self::$instance;
  16.    }
  17.  
  18.    private function __construct()
  19.    {
  20.        if(!$this->test())
  21.        {
  22.            session_start();
  23.            if($this->get("activity")) // zawiera czas ostatniej aktywnosci uzytkownika
  24.            {
  25.                    if(time()-$this->get("activity")>$GLOBALS['session_expired_time'])
  26.                    {
  27.                        $this->destroy();
  28.                    }
  29.                    $this->set("activity",time());
  30.            }
  31.            else if ($this->get("loggedin"))
  32.            {
  33.                $this->set("activity",time());
  34.            }
  35.        }
  36.        $this->id = $this->get("id");
  37.        $this->profile_data = $this->get("profile_data");
  38.    }    
  39.  
  40.    function test()
  41.    {
  42.        if(session_id()=="")
  43.        {
  44.            return false;
  45.        }
  46.        else
  47.        {
  48.            return true;
  49.        }    
  50.    }
  51.    function destroy()
  52.    {
  53.        if(Sesja::test())
  54.        {
  55.            fb::info("Zamykam sesję");
  56.            $this->set("loggedin",false);
  57.            $this->set("activity",false);
  58.            session_destroy();
  59.        }
  60.    }
  61.    function set($key,$val)
  62.    {
  63.        if(Sesja::test())
  64.        {
  65.            $_SESSION[$key]=$val;
  66.        }
  67.    }
  68.    function get($key)
  69.    {
  70.        if(Sesja::test() && array_key_exists($key, $_SESSION))
  71.        {
  72.            return $_SESSION[$key];
  73.        }
  74.        return false;
  75.    }    
  76. }
  77. ?>


... oraz uzytkownik ...

  1. <?php
  2. class Uzytkownik
  3. {
  4.    public $nazwa;
  5.    protected $haslo;
  6.    protected $ziarno;
  7.    protected $id;
  8.    public $email;
  9.    public $status;
  10.    public $profil_id;
  11.    
  12.    function __construct()
  13.    {
  14.        $sesja = Sesja::getInstance();
  15.        $tab_users = TabUsers::getInstance();
  16.        
  17.        if($sesja->test())
  18.        {
  19.            $this->nazwa=$sesja->get("name");
  20.            $this->id=$sesja->get("id");
  21.            $this->status=$sesja->get("status");
  22.            $this->email = $tab_users->getEmail($sesja->get("id"));
  23.        }
  24.    }
  25. ?>


  1. <?php
  2. function zarejestruj()
  3.    {
  4.        $tab_users = TabUsers::getInstance();
  5.        if($tab_users->existsUser($this->nazwa) == true) { echo "Istnieje już taki user! $this->nazwa<br>"; return false; }
  6.        if($tab_users->existsMail($this->email) == true) { echo "Istnieje już taki email! $this->email<br>"; return false; }
  7.      
  8.        $tab_users->addUser($this->nazwa, $this->haslo, $this->ziarno, $this->email);
  9.        return true;
  10.    }
  11.  
  12.    function setNazwa($nazwa)
  13.    {
  14.        $this->nazwa = stripslashes($nazwa);
  15.    }
  16.    function getNazwa()
  17.    {
  18.        return $this->nazwa;
  19.    }
  20.  
  21.    function setHaslo($haslo, $haslo2)
  22.    {
  23.        if($haslo != $haslo2) { echo "Różne hasła!<br>"; return false; }
  24.        if(empty($haslo) || empty($haslo2)) { echo "Jedno z haseł jest puste!<br>"; return false; }
  25.  
  26.        $this->ziarno=time();
  27.        $this->haslo = md5(stripslashes($haslo).$this->ziarno);
  28.        return true;
  29.    }
  30.  
  31.    function setEmail($email)
  32.    {
  33.        $this->email = stripslashes($email);
  34.    }
  35.    function loginUser($username,$password)
  36.    {
  37.        if(empty($username) || empty($password)) { echo "Nie podałeś loginu lub hasła<br>"; return false; }
  38.      
  39.        $tab_users = TabUsers::getInstance();
  40.        $sesja = Sesja::getInstance();
  41.      
  42.        fb::info($tab_users->existsUser($username),"existsUser($username)");
  43.        fb::info($tab_users->existsMail($username),"existsMail($username)");
  44.      
  45.        if(!$tab_users->existsUser($username))
  46.        {
  47.            if($tab_users->existsMail($username))
  48.            {
  49.                $this->id = $tab_users->getIdFromMail($username); // tak naprawde username to mail w tym wypadku
  50.                $this->nazwa = $tab_users->getNameFromId($this->id);
  51.            }
  52.            else
  53.            {
  54.                echo "Taki user nie istnieje!";
  55.                return false;
  56.            }
  57.        }
  58.        else
  59.        {
  60.            $this->id = $tab_users->getId($username);
  61.            $this->nazwa = $username;
  62.        }
  63.  
  64.        $this->haslo = md5($password.$tab_users->getSeed($this->nazwa));
  65.        $this->status = $tab_users->getStatus($this->nazwa);
  66.        $this->ziarno = $tab_users->getSeed($this->nazwa);
  67.      
  68.        if(!$tab_users->checkPass($this->nazwa,$this->haslo)) { echo "Złe hasło!"; return false; }
  69.      
  70.        $sesja->set("id",$this->id);
  71.        $sesja->set("name",$this->nazwa);
  72.        $sesja->set("loggedin", true);
  73.        $sesja->set("status",$this->status);
  74.      
  75.        return true;
  76.    }
  77.    function setProfil($id)
  78.    {
  79.        $this->profile_id = $id;
  80.    }
  81.    function logout()
  82.    {
  83.        unset($this->user);
  84.        unset($haslo);
  85.        unset($ziarno);
  86.        unset($id);
  87.        unset($email);
  88.        unset($status);
  89.        unset($profil_id);
  90.  
  91.        $sesja = Sesja::getInstance();
  92.        $sesja->destroy();
  93.    }
  94.  
  95. }
  96. ?>


To chyba wszystko. WIEEEEEEM, że sporo można zrobić lepiej i łatwiej, ale i tak jestem happy, że działa i poza wzorcem singletona chyba reszte zrobiłem sam. Ale za każde uwagi bede bardzo wdzieczny (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.12.2025 - 00:27