PHP/Autoryzacja i logowanie

Z Wikibooks, biblioteki wolnych podręczników.

< PHP

Spis treści

[edytuj] Przygotowania

Skrypt, który tu napiszemy nie będzie dobrze działał po skopiowaniu i wklejeniu, mam raczej zamiar pokazać rozwiązania rozmaitych problemów.
Na początku należy stworzyć w bazie danych tabelę `users`, oraz wrzucić trochę przykładowych danych:

CREATE TABLE `users` (
     `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
     `name` TEXT NOT NULL,
     `password` TEXT NOT NULL,
     `regdate` DATE NOT NULL,
     `email` TEXT NOT NULL,
     `ranga` INT NOT NULL
);
INSERT INTO `users` ( `id` , `name` , `password` , `regdate` , `email` , `ranga` ) 
VALUES (
NULL , 'admin', MD5('super tajne'), '2007-10-05', 'mail@poczta.pl', 1
);
INSERT INTO `users` ( `id` , `name` , `password` , `regdate` , `email` , `ranga` ) 
VALUES (
NULL , 'user', MD5('tajne'), '2007-10-07', 'innymail@poczta.pl', 2
);
CREATE TABLE `ranks` (
     `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
     `name` TEXT NOT NULL,
     `hash` TEXT NOT NULL
);
INSERT INTO `ranks` (`name`, `hash`) VALUES("Administratorzy", "admins");
INSERT INTO `ranks` (`name`, `hash`) VALUES("Użytkownicy", "users")

A teraz opiszę pokrótce co znaczy które pole: Tabela users: `name` - Nazwa użytkownika, `password` - Hasło, `regdate` - Data rejestracji, `email` - Email, `ranga` - id rangi z tabeli ranks, Tabela ranks: `name` - Czytelna dla ludzi nazwa rangi, `hash` - Nazwa rangi czytelna dla PHP.

[edytuj] Formularz logowania

Teraz należy stworzyć formularz (w (X)HTML), na przykład:

<form action="zaloguj.php" method="post">
    <label for="login">Login: </label><input type="text" name="login"/>
    <label for="password">Hasło: </label><input type="text" name="password"/>
    <input type="submit" value="zaloguj"/>
</form>

A teraz obsługa, czyli plik zaloguj.php:

<?php
interface storage {
    public function login($name, $pass);//1
}
class mysqlStorage implements storage{//2
    public function login($name, $pass){//3
        global $pdo;
        $pdo=new PDO('mysql:host=localhost;dbname=nazwabazy', 'root', 'root');
        $stmt=$pdo->prepare('SELECT name, ranga FROM `users` WHERE name=:name AND password=:password');
        $stmt->bindValue(':name', $name);
        $stmt->bindValue(':password', $pass);
        $stmt->execute();
        $user=$stmt->fetch();
        if($user){
            return $user;
        }
        return false;
    }// login();
}//mysqlStorage
class user{//4
    public $name;
    public $rank;
 
    private $storage;
    public function __construct($storage){
         $this->storage=$storage;
         }
    public function zaloguj(){
         if($_SERVER['REQUEST_METHOD']=='POST'){
             $user=$this->storage->login($_POST['login'], $_POST['password']); 
             if(!$user){die('Nieprawidłowa nazwa użytkownika lub hasło!');}
             $this->name=$user['name'];
             $this->rank=$user['ranga'];
             $_SESSION['zalogowany']=true;
             $_SESSION['name']=$this->name;
             $_SESSION['rank']=$this->rank;
             }
         }
    }
    $user=new user(new mysqlStorage);
    $user->zaloguj()
 
?>
  1. Tworzymy interfejs, który należy zaimplementować aby stworzyć sterownik przechowywania danych
  2. Ta klasa to sterownik przechowywania danych w bazie danych MySQL
  3. Funkcja pobiera dane ze źródła przechowywania(czyli w tym wypadku bazy danych), i zwraca je, jeśli nie ma użytkownika to zwraca false.
  4. Teraz najważniejsza klasa ;). Służy ona do logowania użytkownika, w konstruktorze przyjmuje instancję klasy przechowującej dane.

Dlaczego stworzyliśmy interfejs storage? Aby było można szybko i łatwo zmienić sposób przechowywania danych.

[edytuj] Rejestracja

Teraz napiszemy moduł rejestracji. Do interfejsu dopisz metodę która rejestruje użytkownika:

<?php
public function rejestracja($name, $password, $email, $regdate);
?>

Teraz implementacja w klasie mysqlStorage:

<?php
public function rejestracja($name, $password, $email, $regdate){
    $stmt=$pdo->prepare('INSERT INTO `users` VALUES(NULL, :name, :password, :email, :regdate, 2)');
    $stmt->bindValue(':name', $name);
    $stmt->bindValue(':password', md5($password));
    $stmt->bindValue(':email', $email);
    $stmt->bindValue(':regdate', $regdate);
    $stmt->execute();
    }
?>

Chyba jasne? Ta dwójka na końcu zapytania to numer rangi. Dalej - klasa user:

<?php
public function register(){
     $this->storage->rejestracja($_POST['name'], $_POST['password'], $_POST['email'], date('d-m-Y'));
     }
?>

Formularza pokazywał nie będę.

[edytuj] Ćwiczenia

  1. Napisz panel administracyjny z następującymi funkcjami:
    • Usuwanie użytkownika
    • Zmiana rangi