Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa do autoryzacji użytkowników, prośba o opinię poprawności kodu "zaawansowanego programisty"
Jarod
post
Post #1





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

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


Moje pytanie skierowane jest głównie do osób, które czytały książkę "PHP5 zaawansowane programowanie",
ponieważ problem dotyczy przykładu tam przedstawionego. W rozdziale 15 autor przedstawił klasę do obsługi
własnych sesji a w rozdziale 22 wdraża ją do użytku.

Na stronie 457 przedstawiony jest sposób logowania, który moim zdaniem jest całkowicie bez sensu. Przytoczę tutaj
główny kod:

  1. <?php
  2. (..)
  3. (..)
  4. (..)
  5.  
  6. $session = new WidgetSession (array ('phptype' => "pgsql",
  7.  'hostspec' => "localhost",
  8.  'database' => "artykulandia",
  9.  'username' => "wuser",
  10.  'password' => "foobar"));
  11.  
  12. $session->Impress();
  13. (...)
  14.  
  15. if ($_REQUEST["action" == "login") {
  16.  $session->login($_REQUEST["login_name"].$_REQUEST["login_pass"]);
  17.  if ($session->isLoggedIn()) {
  18.  $smarty->assign_by_ref("user",$session->getUserObject());
  19.  $smarty_>display("main.tpl");
  20.  exit;
  21.  }
  22.  else {
  23.  $smarty->assign('error', "Nieudane logowanie...");
  24.  $smarty_>display("login.tpl");
  25.  exit;
  26.  }
  27. } else {
  28. if ($session->isLoggedIn() == true) {
  29.  $smarty->assign_by_ref("user",$session->getUserObject());
  30.  $smarty_>display("main.tpl");
  31.  exit;
  32. } 
  33. }
  34. ?>


Mniej więcej tak to wygląda. Nie będę podawał kodu klasy bo za dużo pisania. Zresztą nie chodzi mi o sposób
napisania klasy. Wywoływany jest skrypt index.php, który sprawdza czy przesłano parametr action=login.
Jeżeli tak to znaczy, że dokonano próby logowania (wypełniono formularz i go wysłano), metoda sprawdza dane
w bazie - jeżeli się zgadzają ustawia właściwość prywatną klasy logged_in na true. Następnie metoda isLoggedIn()
sprawdza czy wartość właściwości logged_in ma wartość true - jeśli tak uznaje, że użytkownik się zalogował
i ma dostęp do super tajnych danych (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Wszyscy wiemy, że protokół HTTP jest bezstanowy. Więc możemy sobie w jednym skrypcie utworzyć 100 obiektów,
ale jak przejdziemy do drugiego skrytpu (czyli zacznie być wykonywany inny skrypt) to te nasze 100 obiektów
poszło się jeb**.

Wiecie do czego zmierzam? Do tego, że stosując metodę autora po oddaniu sterownia do drugiego skryptu będziemy
musieli utworzyć od nowa obiekt, który będzie miał właściwość logged_in=false (bezstanowość protokołu - zgubiliśmy
dane, że użytkownik jest zalogowany) co wymusza przekierowanie na stronę logowania..

Nie odpalałem całego kodu bo nie chce mi się klepać z książki.. Ale uważam, że jeśli dodamy sprawdzanie
w każdym skrypcie czy użytkownik jest zalogowany to ten sposób nie zadziała. A trzeba sprawdzać czy użytkownik
jest zalogowany, że sprytny user zamiast wpisać www.testowa.pl nie wpisał www.testowa.pl/tajnedane.php i w ten
sposób pominął ekran logowania.


Co o tym myślicie? Bo ja czasem czytająć tą książke miałem wrażenie, że autorzy nie wiedzą co piszą albo piszą kod od niechcenia.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
dr_bonzo
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


A czy w konstruktorze $native_session_id nie jest jakos inicjowane?
Bez reszty kodu trudno mi powiedziec co sie tam dzieje.
Go to the top of the page
+Quote Post
Jarod
post
Post #3





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

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


Cytat(dr_bonzo @ 8.10.2006, 07:49:35 ) *
A czy w konstruktorze $native_session_id nie jest jakos inicjowane?

No właśnie nie.

Cytat(dr_bonzo @ 8.10.2006, 07:49:35 ) *
Bez reszty kodu trudno mi powiedziec co sie tam dzieje.


Tu wklejam kod klasu UserSession. Na tym kodzie opiera się WidgetSession
  1. <?php
  2. class UserSession {
  3. private $php_session_id;
  4. private $native_session_id;
  5. private $dbhandle;
  6. private $logged_in;
  7. private $user_id;
  8. private $session_timeout = 600; # 10 minutowy maksymalny czas nieaktywności sesji
  9. private $session_lifespan = 3600; # 1 godzinny maksymalny czas trwania sesji.
  10.  
  11. public function __construct() {
  12. # Łączy z bazą danych
  13. $this->dbhandle = pg_connect("host=db dbname=prophp5 user=edek") or die ("Błąd PostgreSQL: --> " . pg_last_error($this->dbhandle));
  14. # Inicjalizuje mechanizm obsługi sesji
  15. array(&$this, '_session_open_method'), 
  16. array(&$this, '_session_close_method'), 
  17. array(&$this, '_session_read_method'), 
  18. array(&$this, '_session_write_method'), 
  19. array(&$this, '_session_destroy_method'), 
  20. array(&$this, '_session_gc_method')
  21. );
  22. # Sprawdza przesłane cookie o ile je przesłano; jeżeli wygląda podejrzanie zosta
    ja z miejsca anulowane  
  23. $strUserAgent = $GLOBALS["HTTP_USER_AGENT"];
  24. if ($_COOKIE["PHPSESSID"]) {
  25.  # Kontrola bezpieczeństwa i ważności
  26.  $this->php_session_id = $_COOKIE["PHPSESSID"];
  27.  $stmt = "SELECT id FROM "sesja_uzytkownika" WHERE identyfikator_sesji_ascii = '" . $this->php_session_id . "' AND ((now() - utworzono) < ' " . $this->session_lifespan . " seconds') AND user_agent='" . $strUserAgent . "' AND ((now() - ostatnia_reakcja) <= '".$this->session_timeout." seconds' OR ostatnia_reakcja IS NULL)";
  28.  $result = pg_query($stmt);
  29.  if (pg_num_rows($result)==0) {
  30.  # Ustawia znacznik niepowodzenia
  31. $failed = 1;
  32.  # Usuwa z bazy danych - w tym samym czasie usuwane są przeterminowane sesje
  33.  $result = pg_query("DELETE FROM "sesja_uzytkownika" WHERE (identyfikator_sesji_ascii = '". $this->php_session_id . "') OR (now() - utworzono) > $maxlifetime)");
  34.  # Usuwa nieprzydatne zmienne sesji
  35.  $result = pg_query("DELETE FROM "zmienna_sesji" WHERE identyfikator_sesji NOT IN (SELECT id FROM "sesja_użytkownika")");
  36.  # Pozbywa się identyfikatora, wymuszając na php nadanie nowego
  37.  unset($_COOKIE["PHPSESSID"]);
  38.  };
  39. };
  40. # Ustawia czas życia cookie
  41. session_set_cookie_params($this->session_lifespan);
  42. # Wywołuje metodę session_start by zainicjować sesję
  43. }
  44.  
  45. public function Impress() {
  46. if ($this->native_session_id) {
  47. $result = pg_query("UPDATE "sesja_uzytkownika" SET ostatnia_reakcja = now() WHERE id = " . $this->native_session_id);
  48. };
  49. }
  50.  
  51. public function IsLoggedIn() {
  52. return($this->logged_in);
  53. }
  54.  
  55. public function GetUserID() {
  56. if ($this->logged_in) {
  57. return($this->user_id);
  58. } else {
  59. return(false);
  60. };
  61. }
  62.  
  63. public function GetUserObject() {
  64. if ($this->logged_in) {
  65. if (class_exists("user")) {
  66. $objUser = new User($this->user_id);
  67. return($objUser);
  68. } else {
  69. return(false);
  70. };
  71. };
  72. }
  73.  
  74. public function GetSessionIdentifier() {
  75. return($this->php_session_id);
  76. }
  77.  
  78. public function Login($strUsername, $strPlainPassword) {
  79.  $strMD5Password = md5($strPlainPassword);
  80.  $stmt = "SELECT id FROM "uzytkownik" WHERE nazwa_uzytkownika = '$strUsername' AND md5_haslo = '$strMD5Password'";
  81.  $result = pg_query($stmt);
  82.  if (pg_num_rows($result)>0) {
  83. $row = pg_fetch_array($result);
  84. $this->user_id = $row["id"];
  85. $this->logged_in = true;
  86. $result = pg_query("UPDATE "sesja_uzytkownika" SET zalogowany = true, identyfikator_uzytkownika = " . $this->user_id . " WHERE id = " . $this->native_session_id);
  87. return(true);
  88.  } else {
  89. return(false);
  90.  };
  91. }
  92.  
  93. public function LogOut() {
  94.  if ($this->logged_in == true) {
  95. $result = pg_query("UPDATE "sesja_uzytkownika" SET zalogowany = false, identyfikator_uzytkownika = 0 WHERE id = " . $this->native_session_id);
  96. $this->logged_in = false;
  97. $this->user_id = 0;
  98. return(true);
  99.  } else {
  100. return(false);
  101.  };
  102. }
  103.  
  104. public function __get($nm) {
  105.  $result = pg_query("SELECT wartosc_zmiennej FROM zmienna_sesji WHERE identyfikator_sesji = " . $this->native_session_id . " AND nazwa_zmiennej = '" . $nm . "'");
  106.  if (pg_num_rows($result)>0) {
  107. $row = pg_fetch_array($result);
  108. return(unserialize($row["wartosc_zmiennej"]));
  109.  } else {
  110. return(false);
  111.  };
  112. }
  113.  
  114.  
  115. public function __set($nm, $val) {
  116.  $strSer = serialize($val);
  117.  $stmt = "INSERT INTO zmienna_sesji(identyfikator_sesji, nazwa_zmiennej, wartosc_zmiennej) VALUES(" . $this->native_session_id . ", '$nm', '$strSer')";
  118.  $result = pg_query($stmt);
  119. }
  120.  
  121.  
  122. private function _session_open_method($save_path, $session_name) {
  123. # Do nothing
  124. return(true);
  125. }
  126.  
  127. private function _session_close_method() {
  128. pg_close($this->dbhandle);
  129. return(true);
  130. }
  131.  
  132. private function _session_read_method($id) {
  133.  # Służy do ustalenia, czy nasza sesja w ogóle istnieje
  134.  $strUserAgent = $GLOBALS["HTTP_USER_AGENT"];
  135.  $this->php_session_id = $id;
  136.  # Na razie ustawia znacznik niepowodzenie na 1
  137.  $failed = 1;
  138.  # Sprawdza czy sesja istnieje w bazie danych
  139.  $result = pg_query("SELECT id, zalogowany, identyfikator_uzytkownika FROM "sesja_uzytkownika" WHERE identyfikator_sesji_ascii = '$id'");
  140.  if (pg_num_rows($result)>0) {
  141. $row = pg_fetch_array($result);
  142. $this->native_session_id = $row["id"];
  143. if ($row["zalogowany"]=="t") {
  144.  $this->logged_in = true;
  145.  $this->user_id = $row["identyfikator_uzytkownika"];
  146. } else {
  147.  $this->logged_in = false;
  148. };
  149.  } else {
  150. $this->logged_in = false;
  151. # Konieczne jest stworzenie wpisu w bazie danych
  152. $result = pg_query("INSERT INTO sesja_uzytkownika(identyfikator_sesji_ascii, zalogowany, identyfikator_uzytkownika, utworzono
    , user_agent) VALUES ('$id','f',0,now(),'$strUserAgent')"
    );
  153. # Teraz pobiera prawdziwy identyfikator
  154. $result = pg_query("SELECT id from "sesja_uzytkownika" WHERE identyfikator_sesji_ascii = '$id'");
  155. $row = pg_fetch_array($result);
  156. $this->native_session_id = $row["id"];
  157.  };
  158.  # Zwraca jedynie ciąg pusty
  159.  return("");
  160. }
  161.  
  162. private function _session_write_method($id, $sess_data) {
  163.  return(true);
  164. }
  165.  
  166. private function _session_destroy_method($id) {
  167.  $result = pg_query("DELETE FROM "sesja_uzytkownika" WHERE identyfikator_sesji_ascii = '$id'");
  168.  return($result);
  169. }
  170.  
  171.  
  172. private function _session_gc_method($maxlifetime) {
  173. return(true);
  174. }
  175.  
  176.  
  177. }
  178. ?>
Go to the top of the page
+Quote Post

Posty w temacie


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: 9.10.2025 - 07:55