[PHP] System logowania

Dzisiaj napiszemy sobie skrypt logowania do wcześniejszej stworzonego skryptu rejestracji użytkowników. Skrypt będzie składał się z trzech plików login.php, logged.php oraz logout.php. Rozbudujemy także wcześniej napisaną klasę User o nowe metody.

Formularz logowania

Standardowo na początku tworzymy formularz. Wystarczy tylko skopiować go z artykułu o systemie rejestracji i usunąć pola 'Powtórz hasło' i 'E-mail' .

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" type="text/css" media="screen" />
  
  <title>Logowanie</title>
 </head>
 <body>
  <div class="container">
   <h1>Zaloguj się</h1>
   <form action="" method="post">
    <div class="form-group">
     <p><label for="username">Nazwa użytkownika</label><input type="text" name="username" id="username" class="form-control" placeholder="Nazwa użytkownika" required /></p>
    </div>
    <div class="form-group">
     <p><label for="password">Hasło</label><input type="password" name="password" id="password" class="form-control" placeholder="Hasło" required /></p>
    </div>
    <p><input type="submit" class="btn btn-primary" value="Zaloguj" /></p>
   </form>
  </div>
 </body>
</html>

Skrypt logowania

Teraz stworzymy skrypt login.php odpowiadający za zalogowanie użytkownika:

<?php

 ini_set('display_errors', '1');
 
 error_reporting(E_ALL);
 
 if(!isset($_POST['username'])):
 
?>

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" type="text/css" media="screen" />
  
  <title>Logowanie</title>
 </head>
 <body>
  <div class="container">
   <h1>Zaloguj się</h1>
   <form action="" method="post">
    <div class="form-group">
     <p><label for="username">Nazwa użytkownika</label><input type="text" name="username" id="username" class="form-control" placeholder="Nazwa użytkownika" required /></p>
    </div>
    <div class="form-group">
     <p><label for="password">Hasło</label><input type="password" name="password" id="password" class="form-control" placeholder="Hasło" required /></p>
    </div>
    <p><input type="submit" class="btn btn-primary" value="Zaloguj" /></p>
   </form>
  </div>
 </body>
</html>

<?php else: ?>

<?php

 if(!empty($_POST['username']) && !empty($_POST['password'])) {
 
  if(strlen($_POST['username']) >= 3) {
  
   if(strlen($_POST['username']) <= 30) {
   
    if(strlen($_POST['password']) >= 6) {
    
     if(strlen($_POST['password']) <= 16) {
     
      require 'set-db-connection.php';
      require 'class.user.php';
      
      $username = preg_replace('/[^\p{L}\p{N}]/iu', '', $_POST['username']);
      
      $user = new User($dbh);
      
      if($user->login($username, $_POST['password'])) {
      
       session_start();
       
       $_SESSION['logged'] = 1;
       $_SESSION['username'] = $username;
       
       header('Location: logged.php');
       
       exit;
       
      }
      
      else {
      
       echo '<p>Błędne dane logowania.</p>';
       
      }
      
     }
     
     else {
     
      echo '<p>Hasło jest zbyt długie.</p>';
      
     }
     
    }
    
    else {
    
     echo '<p>Hasło jest zbyt krótkie.</p>';
     
    }
    
   }
   
   else {
   
    echo '<p>Nazwa użytkownika jest zbyt długa.</p>';
    
   }
   
  }
  
  else {
  
   echo '<p>Nazwa użytkownika jest zbyt krótka.</p>';
   
  }
  
 }
 
 else {
 
  echo '<p>Wypełnij wszystkie pola, aby się zalogować.</p>';
  
 }
 
?>

<?php endif; ?>

Klasa User

Dodamy teraz do utworzonej w poprzednim artykule klasy User nową metodę - login.

<?php

 class User {
 
  function __construct($dbh) {
  
   $this->dbh = $dbh;
   
  }
  
  public function login($username, $password) {
  
   $sth = $this->dbh->prepare('SELECT password FROM users WHERE username = :username LIMIT 1');
   
   $sth->bindParam(':username', $username, PDO::PARAM_STR);
   
   $sth->execute();
   
   $row = $sth->fetch(PDO::FETCH_ASSOC);
   
   if($row && password_verify($password, $row['password']) === true) {
   
    return true;
    
   }
   
   else return false;
   
  }
  
  public function user_exist($username, $email) {
  
   $sth = $this->dbh->prepare('SELECT id FROM users WHERE username = :username OR email = :email LIMIT 1');
   
   $sth->bindParam(':username', $username, PDO::PARAM_STR);
   $sth->bindParam(':email', $email, PDO::PARAM_STR);
   
   $sth->execute();
   
   return $sth->fetch(PDO::FETCH_ASSOC);
   
  }
  
  public function insert_user($username, $email, $password, $ip) {
  
   $sth = $this->dbh->prepare("INSERT INTO users (id, registered_timestamp, username, email, password, ip) VALUES('', CURRENT_TIMESTAMP(), :username, :email, :password, :ip)");
   
   $sth->bindParam(':username', $username, PDO::PARAM_STR);
   $sth->bindParam(':email', $email, PDO::PARAM_STR);
   $sth->bindParam(':password', $password, PDO::PARAM_STR);
   $sth->bindParam(':ip', $ip, PDO::PARAM_STR);
   
   return $sth->execute();
   
  }
  
 }

Plik logged.php

Plik logged.php to strona, na którą użytkownik zostanie przekierowany po poprawnym zalogowaniu. Na stronie tej będzie informacja o zalogowaniu oraz link do strony logout.php

<?php

 session_start();
 
 if(!isset($_SESSION['logged'])) {
 
  header('Location: login.php');
  
  exit;
  
 }
 
?>

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  
  <title>Zalogowany</title>
  
 </head>
 <body>
  <div>
  <?php
  
  if(isset($_SESSION['logged'])):
  
  ?>
  
  <p>Jesteś zalogowany jako <strong><?= $_SESSION['username']; ?></strong>.</p>
  <p><a href="logout.php">Wyloguj się</a></p>
  
  <?php endif; ?>
  </div>
 </body>
</html>

Plik logout.php

Jeszcze tylko plik wylogowywujący i to wszystko. W pliku tym usuwamy zmienne sesyjne, które utworzyliśmy podczas zalogowania oraz niszczymy aktualną sesje funkcją session_destroy.

<?php

 session_start();
 
 unset($_SESSION['logged']);
 unset($_SESSION['username']);
 
 session_destroy();
 
 header('Location: login.php');
 
 exit;

Aktualna wersja skryptu dostępna jest także na GitHub.

Komentarze

Prześlij komentarz

Dzięki za komentarz!

Popular

[HTML] Jak wstawić obrazek?

[C++] Jak obliczyć pole i obwód trapezu?

[PHP] Jak pobrać adres strony?