Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] System logowania
Forum PHP.pl > Forum > PHP
MGreg
Witam. Stworzyłem system logowania i chciałbym, abyście sprawdzili, czy jest w miarę szczelny. Dane do logowania osadziłem w skrypcie na sztywno tj. login admin, hasło 123 - dane te będą pobierane z bazy danych oczywiście z zabezpieczeniem przed sql injection. Teraz jednak chodzi mi o sam system logowania.

login.php
  1. <?php
  2.  
  3.  #wylgowywanie
  4.  function logout(){
  5.      if($_SESSION['logged']==1){
  6.          $_SESSION['logged']=0;
  7.          return true;
  8.      }    
  9.  }
  10.  
  11.  if($_GET['a']=='logout'){
  12.      if(logout()==true){
  13.          echo "Zostałeś wylogowany";
  14.      }
  15.      else{
  16.          echo "nie byłeś zalogowany";
  17.      }
  18.  }
  19.  
  20.  #logowanie
  21.  function logged(){
  22.      if($_SESSION['logged']==0){    
  23.          if($_GET['a']=='login'){        
  24.              if($_POST['login'] and $_POST['password']){            
  25.                  if($_POST['login']=='admin' and $_POST['password']=='123'){
  26.                      $_SESSION['logged']=1;
  27.                      $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
  28.                      if($_SESSION['logged']==1){
  29.                      return true;
  30.                      }                
  31.                  }
  32.                  else{
  33.                      return false;                
  34.                  }            
  35.              }        
  36.          }
  37.      }
  38.      else{
  39.          if($_SESSION['ip']==$_SERVER['REMOTE_ADDR'] and $_SESSION['logged']==1){
  40.              return true;
  41.          }    
  42.      }
  43.  }
  44.  
  45.  if(logged()==false){
  46.      include('template/login_form.php');
  47.  }
  48.  else{
  49.      echo "zalogowany";
  50.      echo "<a href=login.php?a=logout>Wyloguj</a>";
  51.  }
  52.  ?>


template/login_form.php
  1. <form action="login.php?a=login" method=POST>
  2. Login:<input type=text name=login>
  3. Hasło:<input type=password name=password>
  4. <input type=submit value="zaloguj">
  5. </form>


Jak widać na początku skryptu generowany jest losowy identyfikator sesji, w przypadku gdyby został w jakiś sposób skradziony dodałem jeszcze porównywanie IP, jeśli się nie zgadza logged() zwraca false.
Axexis
Za każdym odświeżeniem strony zmieniasz ID sesji. Nie kasują Ci się za każdym razem dane? d;

Dwa. Co jeśli ktoś ma proxy zmieniające IP co odświeżenie strony?
Trzy. Przy wylogowaniu wystarczy unset($_SESSION['logged']);.
Cztery. Jak sprawdzasz czy funkcja została wykonana wystarczy if(funkcja()).
MGreg
Zmieniłem trochę cały system, jeśli ktoś może to prosiłbym posprawdzać czy jest w miarę bezpieczny. Jeśli występuje jakaś dziura to prosiłbym byście mi napisali. Byście wszystkie sesje dokładnie widzieli dodałem wyświetlanie całej tablicy $_SESSION.

  1. <?php
  2. $NowTime = time(); #obecny czas
  3. $SessTime = 3600; #czas trwania sesji
  4. $LoggedTime = 300; #czas trwania sesji podczas bezczynności
  5.  
  6. $login_form = "<form action=\"login.php?a=login\" method=POST>
  7.     Login:<input type=text name=login>
  8.     Hasło:<input type=password name=password>
  9.     <input type=submit value=\"zaloguj\">
  10. </form>";
  11.  
  12. #sprawdza czy jest zarejestrowana sesja
  13. function check_session(){
  14.     if(isset($_SESSION['logged'])){
  15.         return true;
  16.     }
  17.     else{        
  18.         return false;
  19.     }
  20. }
  21.  
  22. #sprawdza dane z formularza
  23. function check_form(){
  24.     if($_POST['login'] and $_POST['password']){
  25.         if(addslashes($_POST['login'])=='admin' and addslashes($_POST['password'])=='123'){
  26.             return true;
  27.         }
  28.         else{
  29.             return false;
  30.         }
  31.     }
  32. }
  33.  
  34. #zakańcza sesję
  35. function end_session(){
  36.     if(check_session()){
  37.         unset($_SESSION['logged']);
  38.         unset($_SESSION['last_refresh']);
  39.         unset($_SESSION['session_start']);
  40.         unset($_SESSION['user_login']);
  41.     }
  42. }
  43.  
  44. #kontynuacja sesji
  45. function continue_session(){
  46.     global $NowTime;
  47.     global $LoggedTime;
  48.     global $SessTime;
  49.    
  50.     #sprawdza czy nie upłynął czas trwania sesji, lub czy sesja jest zbyt długo bezczynna
  51.     if(isset($_SESSION['last_refresh'])){
  52.         if(($_SESSION['last_refresh']+$LoggedTime < $NowTime) or ($_SESSION['session_start']+$SessTime < $NowTime)){
  53.             return false;            
  54.         }
  55.         else{
  56.             $_SESSION['last_refresh']= $NowTime;
  57.         }
  58.         return true;
  59.     }
  60.     else{
  61.         $_SESSION['last_refresh']= $NowTime;        
  62.         return true;
  63.     }
  64. }
  65.  
  66. #właściwa funckja zarządzania sesjami
  67. function session(){
  68.     global $NowTime;
  69.     global $login_form;
  70.    
  71.     if(check_session()){
  72.         if(continue_session()){
  73.             echo "Zalogowany jako:<b> ".$_SESSION['user_login']."</b> <a href=login.php?a=logout>wyloguj</a>";
  74.             return true;
  75.         }
  76.         else{
  77.             end_session();
  78.             header("location:login.php");
  79.         }
  80.     }
  81.    
  82.     else{        
  83.         if(check_form()){
  84.             $_SESSION['logged']=1;
  85.             $_SESSION['session_start'] = $NowTime;
  86.             $_SESSION['user_login'] = $_POST['login'];
  87.             header("location:login.php");
  88.         }
  89.         echo $login_form;
  90.     }
  91. }
  92.  
  93. if($_GET['a']=="logout"){
  94.     end_session();
  95.     header("location:login.php");
  96. }
  97.  
  98. session();
  99.  
  100. echo '<pre>';
  101. print_r( $_SESSION);
  102.  echo '</pre>';  
  103. ?>
Albitos
Masz podatność na ataki typu session fixation, poza tym ustaw sobie na początku skryptu error_reporting(E_ALL)...
MGreg
Skorzystałem za artykułu na stronie i na początku w.w skryptu dodałem
  1. <?php
  2. $regenerateReq = 10;
  3.  
  4. if(isset($_SESSION['req'])){
  5.    $_SESSION['req']++;
  6. }
  7. else{
  8.    $_SESSION['req']=1;
  9. }
  10.  
  11. if($_SESSION['req']>$regenerateReq){
  12. $_SESSION['req']=1;
  13. }
  14. ?>

Chyba session fixtation mamy już z głowy smile.gif

Cały skrypt wygląda teraz tak:
  1. <?php
  2.  
  3. $NowTime = time(); #obecny czas
  4. $SessTime = 3600; #czas trwania sesji
  5. $LoggedTime = 300; #czas trwania sesji podczas bezczynności
  6. $regenerateReq = 10; #ilość rządań po której zostanie zregenerowany identyfikator sesji
  7.  
  8. if(isset($_SESSION['req'])){
  9.    $_SESSION['req']++;
  10. }
  11. else{
  12.    $_SESSION['req']=1;
  13. }
  14.  
  15. if($_SESSION['req']>$regenerateReq){
  16. $_SESSION['req']=1;
  17. }
  18.  
  19. $login_form = "<form action=\"login.php?a=login\" method=POST>
  20.    Login:<input type=text name=login>
  21.    Hasło:<input type=password name=password>
  22.    <input type=submit value=\"zaloguj\">
  23. </form>";
  24.  
  25. #sprawdza czy jest zarejestrowana sesja
  26. function check_session(){
  27.    if(isset($_SESSION['logged'])){
  28.        return true;
  29.    }
  30.    else{        
  31.        return false;
  32.    }
  33. }
  34.  
  35. #sprawdza dane z formularza
  36. function check_form(){
  37.    if(isset($_POST['login']) and isset($_POST['password'])){
  38.        if(addslashes($_POST['login'])=='admin' and addslashes($_POST['password'])=='123'){
  39.            return true;
  40.        }
  41.        else{
  42.            return false;
  43.        }
  44.    }
  45. }
  46.  
  47. #zakańcza sesję
  48. function end_session(){
  49.    if(check_session()){
  50.        unset($_SESSION['logged']);
  51.        unset($_SESSION['last_refresh']);
  52.        unset($_SESSION['session_start']);
  53.        unset($_SESSION['user_login']);
  54.    }
  55. }
  56.  
  57. #kontynuacja sesji
  58. function continue_session(){
  59.    global $NowTime;
  60.    global $LoggedTime;
  61.    global $SessTime;    
  62.    
  63.    #sprawdza czy nie upłynął czas trwania sesji, lub czy sesja jest zbyt długo bezczynna
  64.    if(isset($_SESSION['last_refresh'])){
  65.        if(($_SESSION['last_refresh']+$LoggedTime < $NowTime) or ($_SESSION['session_start']+$SessTime < $NowTime)){
  66.            return false;            
  67.        }
  68.        else{
  69.            $_SESSION['last_refresh']= $NowTime;
  70.        }
  71.        return true;
  72.    }
  73.    else{
  74.        $_SESSION['last_refresh']= $NowTime;        
  75.        return true;
  76.    }
  77. }
  78.  
  79. #właściwa funckja zarządzania sesjami
  80. function session(){
  81.    global $NowTime;
  82.    global $login_form;
  83.    
  84.    if(check_session()){
  85.        if(continue_session()){
  86.            echo "Zalogowany jako:<b> ".$_SESSION['user_login']."</b> <a href=login.php?a=logout>wyloguj</a>";
  87.            return true;
  88.        }
  89.        else{
  90.            end_session();
  91.            header("location:login.php");
  92.        }
  93.    }
  94.    
  95.    else{        
  96.        if(check_form()){
  97.            $_SESSION['logged']=1;
  98.            $_SESSION['session_start'] = $NowTime;
  99.            $_SESSION['user_login'] = $_POST['login'];
  100.            header("location:login.php");
  101.        }
  102.        echo $login_form;
  103.    }
  104. }
  105. if(isset($_GET['a'])=="logout"){
  106.    end_session();
  107.    header("location:login.php");
  108. }
  109.  
  110. session();
  111.  
  112. echo '<pre>';
  113. print_r( $_SESSION);
  114. echo '</pre>';  
  115. ?>


Jakie mamy zabezpieczenia?
- regeneracja identyfikatora sesji po 10 rządaniach
- zakończenie sesji po 30 minutach
+ jeśli można to uznać za zabezpieczenie
- zakończenie sesji po 5 minutach bezczynności
rzymek01
nie potrzebnie w 42 dajesz addslashes
MGreg
Hehe, dodałem ten addslashes by później nikt nie mówił o braku filtrowania danych. Akurat ten fragment kodu jest na sztywno, w jego miejscu pojawi się pobieranie danych z bazy danych wraz z mysql_real_esape_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.