Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Logowanie i zabezpieczenia
Forum PHP.pl > Forum > Przedszkole
snerf
Witam

napisałem sobie prosty skrypt logowania i starałem się zabezpieczyć sesję póki co się sprawdza lecz nwm czy to jest w pełni bezpieczne rozwiązanie:

  1. <?php
  2. class user{
  3. public $pdo;
  4. public $timeout; public $timeout_active;
  5. public $last_visit_time;
  6. public $prefix_mysql;
  7.  
  8. public function pdo($pdo, $time, $time_activ, $prefix_mysql)
  9. {
  10. $this->pdo = $pdo;
  11. $this->timeout = $time;
  12. $this->timeout_active = $time_activ;
  13. $this->prefix_mysql = $prefix_mysql;
  14. }
  15.  
  16. public function login($name, $password)
  17. {
  18. $pdo = $this->pdo;
  19. try{
  20. $password_sel = set_password($password);
  21. $stmt = $pdo -> prepare('SELECT id, password FROM `'.$this->prefix_mysql.users.'` WHERE username = :user OR email = :user LIMIT 1');
  22. $stmt -> bindValue(':user', $name, PDO::PARAM_STR);
  23. $stmt -> bindValue(':pass', $password_sel, PDO::PARAM_STR);
  24. $stmt -> execute();
  25. $count = $stmt->rowCount();
  26. }catch(PDOException $e){
  27. $display = 'Błąd zapytania:<br> ' . $e->getMessage();
  28. }
  29. $row = $stmt -> fetch();
  30. $user_id = $row['id'];
  31. if($count == 1){
  32. if(check_password($password, $row['password'])){
  33. $display = 'Zalogowano';
  34. $seskey = md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);
  35. $this->last_visit_time = time()+$this->timeout_active;
  36. $stmt = $pdo -> prepare('UPDATE `'.$this->prefix_mysql.users.'` SET `session_key` = :seskey, `time_activ` = :date WHERE `id` = :user_id');
  37. $stmt -> bindValue(':date', $this->last_visit_time, PDO::PARAM_INT);
  38. $stmt -> bindValue(':seskey', $seskey, PDO::PARAM_STR);
  39. $stmt -> bindValue(':user_id', $user_id, PDO::PARAM_INT);
  40. $stmt->execute();
  41. $_SESSION['last_active'] = time();
  42. $_SESSION['owner_ses'] = $seskey;
  43. $_SESSION['user_id'] = $user_id;
  44. }else{
  45. $display = 'Dane nie prawidłowe.';
  46. }
  47. }else{
  48. $display = 'Takie konto nie istnieje.';
  49. }
  50. return $display;
  51. }
  52.  
  53. public function check($ost_activ)
  54. {
  55. if(!empty($_SESSION['user_id']) && !empty($_SESSION['owner_ses'])){
  56. $timeout = $this->timeout;
  57. $owner_ses = md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT']);
  58.  
  59. if ((isset($_SESSION['last_active']) && $_SESSION['last_active']<(time()-$timeout))
  60. || (isset($_SESSION['owner_ses']) && $_SESSION['owner_ses']!=$owner_ses))
  61. {
  62. setcookie(session_name(), '', time()-3600, '/');
  63. header('Location: index.html');
  64. }else{
  65. $_SESSION['last_active'] = time();
  66. $_SESSION['owner_ses'] = $owner_ses;
  67. if($ost_activ < time()){
  68. $this->last_visit_time = time()+$this->timeout_active;
  69. $pdo = $this->pdo;
  70. $stmt = $pdo -> prepare('UPDATE `'.$this->prefix_mysql.users.'` SET `time_activ` = :date WHERE `id` = :user_id AND `session_key` = :seskey');
  71. $stmt -> bindValue(':date', $this->last_visit_time, PDO::PARAM_INT);
  72. $stmt -> bindValue(':seskey', $owner_ses, PDO::PARAM_STR);
  73. $stmt -> bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
  74. $stmt->execute();
  75. }
  76. }
  77. }
  78. }
  79. }
  80.  
  81. $user_class = new user;
  82. $user_class->pdo($pdo,$config['login_time'],$config['login_active_time'], $prefix_mysql);
  83.  
  84. $login = $user_class->login($_POST['email'], $_POST['password']);
  85.  
  86.  
  87. ?>


Jak jeszcze mogę zabezpieczyć logowanie? czy posiada jakieś błędy których nie zauważyłem? chciałbym być pewny przed wydaniem publicznie stronki.

mam nadzieje że to dobry dział, jak nie to przepraszam i prosze o poprawkę smile.gif
Damonsson
W pełni bezpieczne to nie będzie nigdy. Ale wygląda wszystko ok.
snerf
  1. $user_class->check($get_data['time_activ']); //Sprawdzam sesje
zapomniałem dodać...


a mam pytanie czy takie tworzenie dostępu jest poprawne?:
  1. public function get_permission($id)
  2. {
  3. $pdo = $this->pdo;
  4. $stmt = $pdo -> prepare('SELECT `'.$this->prefix_mysql.role_permission.'`.value, `'.$this->prefix_mysql.permissions.'`.string AS string FROM `'.$this->prefix_mysql.role_permission.'` LEFT JOIN `'.$this->prefix_mysql.permissions.'` ON `'.$this->prefix_mysql.role_permission.'`.id_permission = `'.$this->prefix_mysql.permissions.'`.id WHERE `'.$this->prefix_mysql.role_permission.'`.id_groups = :grupa');
  5. $stmt -> bindValue(':grupa', $id, PDO::PARAM_INT);
  6. $stmt -> execute();
  7. while($row = $stmt -> fetch()){
  8. $perm[$row['string']] = $row;
  9. }
  10. return $perm;
  11. }


Ładuje to tak:
  1. $get_perm = $user_class->get_permission($get_data['group']);



A wykorzystuje np w templatkach lub php tak:
  1. if($get_perm['access_edit']['value'] == 1){
  2. //it's works
  3. }



Czy jest to dobry sposób?
Xart
Tak sposób w porządku smile.gif
YourFrog
Co do kodu to jest wporządku. Problemem jest to co wykorzystałeś do obsługi tego kodu, a mianowicie sesje. W momencie gdy będziesz posiadał hosting współdzielony (a będziesz bo wątpie żebyś kupował dedyka) istnieje możliwość dobrania się do twoich plików przechowujących sesje i ich modyfikacji.

Poczytaj o sesjach i jak je zabezpieczać dopiero wtedy to będzie porządne wink.gif Ale żebys mnie źle nie zrozumiał od strony kodu można się jedynie o logikę przyczepić ;p

Osobiście polecam ci olać powyższą część mojego posta, a sesje zastąpić jakimś kontenerem w którym narazie pod maską będą sesje np.

  1. <?php
  2.  
  3. namespace YourFrog;
  4.  
  5. interface SessionInterface
  6. {
  7. /**
  8. * Pobranie wartości z sesji
  9. */
  10. public function get($key, $defaultValue = null);
  11.  
  12. /**
  13. * Sprawdzenie czy wartość w sesji istnieje
  14. */
  15. public function hasElement($key);
  16.  
  17. /**
  18. * Zapisanie wartości w sesji
  19. */
  20. public function set($key, $value);
  21. }
  22.  
  23. /**
  24.  * Fabryka
  25.  */
  26. class SessionFactory
  27. {
  28. private static $_instance;
  29.  
  30. /**
  31. * @return SessionInterface
  32. */
  33. public static function get()
  34. {
  35. if( self::$_instance === null )
  36. self::$_instance = new Session();
  37.  
  38. return self::$_instance;
  39. }
  40. }
  41.  
  42. class Session implements SessionInterface
  43. {
  44. /**
  45. * Ukryty konsturktor
  46. */
  47. public function __construct()
  48. {
  49. $this->sessionStart();
  50. $this->items = $_SESSION;
  51. }
  52.  
  53. private function sessionStart()
  54. {
  55. if( session_status() == PHP_SESSION_NONE )
  56. {
  57. }
  58. }
  59.  
  60. public function get($key, $defaultValue = null)
  61. {
  62. if( $this->hasElement($key) )
  63. return $this->items[$key];
  64.  
  65. return $defaultValue;
  66. }
  67.  
  68. public function hasElement($key)
  69. {
  70. return isset($this->items[$key]);
  71. }
  72.  
  73. public function set($key, $value)
  74. {
  75. $this->items[$key] = $value;
  76. }
  77. }


Musisz wtedy pamiętać tylko żeby wywoływać fabrykę, a nie bezpośrednio klase session, no ale to też można obejść jakimś wzorcem projektowym jak rejestr.
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.