3.2. Uwierzytelnianie w oparciu o tabelę bazy danych

3.2.1. Wprowadzenie

Zend_Auth_Adapter_DbTable zapewnia możliwość przeprowadzenia uwierzytelniania w oparciu o dane przechowywane w tabeli bazy danych. Z tego względu, że klasa Zend_Auth_Adapter_DbTable wymaga przekazania instancji klasy Zend_Db_Adapter_Abstract do jej konstruktora, każda ta instancja jest powiązana z konkretnym połączeniem do bazy danych. Inne opcje konfiguracyjne mogą być ustawione za pomocą konstruktora lub za pomocą metod instancji, po jednej dla każdej z opcji.

Dostępne opcje konfiguracyjne to:

  • tableName: Jest to nazwa tabeli bazy danych, która zawiera dane uwierzytelniania i do której jest przeprowadzane zapytanie uwierzytelniające.

  • identityColumn: Jest to nazwa kolumny tabeli bazy danych, która reprezentuje tożsamość. Kolumna tożsamości musi zawierać unikalne wartości, na przykład takie jak nazwa użytkownika czy adres e-mail.

  • credentialColumn: Jest to nazwa kolumny tabeli bazy danych, która reprezentuje wartość uwierzytelniającą. W prostym schemacie uwierzytelniania opartym o nazwę tożsamości i hasło, wartość uwierzytelniająca odpowiada hasłu. Zobacz także opcję credentialTreatment.

  • credentialTreatment: W wielu przypadkach, hasło i inne wrażliwe dane są zszyfrowane, haszowane, zakodowane, zakryte lub w inny sposób przetworzone przez jakąś funkcję lub algorytm. Określając metodę przerobienia danych, taką jak na przykład 'MD5(?)' czy 'PASSWORD(?)', programista może użyć konkretnej funkcji SQL na danych uwierzytelniających. Z tego względu, że te funkcje są specyficzne dla konkretnych systemów baz danych, zajrzyj do odpowiednich dokumentacji aby sprawdzić dostępność takich funkcji dla twojego systemu bazy danych.

Przykład 3.3. Podstawowe użycie

Jak wyjaśniono we wprowadzeniu, konstruktor klasy Zend_Auth_Adapter_DbTable wymaga przekazania mu instancji klasy Zend_Db_Adapter_Abstract, zapewniającej połączenie do bazy danych, z którym powiązana jest instancja adaptera uwierzytelniania. Na początku powinno być utworzone połączenie do bazy danych.

Poniższy kod tworzy adapter bazy danych przechowywanej w pamięci, tworzy prostą strukturę tabeli, a następnie wstawia wiersz, w oparciu o który przeprowadzimy później zapytanie uwierzytelniające. Ten przykład wymaga dostępnego rozszerzenia PDO SQLite:

<?php
// Tworzymy połączenie do bazy danych SQLite przechowywanej w pamięci
require_once 'Zend/Db/Adapter/Pdo/Sqlite.php';
$dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:'));

// Budujemy zapytanie tworzące prostą tabelę
$sqlCreate = 'CREATE TABLE [users] ( '
           . '[id] INTEGER  NOT NULL PRIMARY KEY, '
           . '[username] VARCHAR(50) UNIQUE NOT NULL, '
           . '[password] VARCHAR(32) NULL, '
           . '[real_name] VARCHAR(150) NULL)';

// Tworzymy tabelę z danymi uwierzytelniania
$dbAdapter->query($sqlCreate);

// Budujemy zapytanie wstawiające wiersz, dla którego możemy przeprowadzić
// próbę uwierzytelniania
$sqlInsert = 'INSERT INTO users (username, password, real_name) '
           . 'VALUES ("my_username", "my_password", "My Real Name")';

// Wstawiamy dane
$dbAdapter->query($sqlInsert);

Gdy połączenie do bazy danych oraz dane w tabeli są już dostępne, może być utworzona instancja Zend_Auth_Adapter_DbTable. Opcje konfiguracyjne mogą być przekazane do konstruktora lub przekazane jako parametry do metod dostępowych już po utworzeniu instancji:

<?php
require_once 'Zend/Auth/Adapter/DbTable.php';

// Konfigurujemy instancję za pomocą parametrów konstruktora...
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter, 'users', 'username', 'password');

// ...lub konfigurujemy instancję za pomocą metod dostępowych
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
            ->setIdentityColumn('username')
            ->setCredentialColumn('password');

W tym momencie intancja adaptera uwierzytelniania jest gotowa do przeprowadzenia zapytań uwierzytelniających. W celu utworzenia zapytania, wejściowe dane uwierzytelniania są przekazywane do adaptera przed wywołaniem metody authenticate():

<?php
// Ustawiamy wartości danych uwierzytelniania (np., z formularza logowania)
$authAdapter->setIdentity('my_username')
            ->setCredential('my_password');

// Przeprowadzamy zapytanie uwierzytelniające, zapisując rezultat
$result = $authAdapter->authenticate();

Oprócz możliwości użycia metody getIdentity() obiektu rezultatu uwierzytelniania, obiekt Zend_Auth_Adapter_DbTable pozwala także na odebranie wiersza tabeli po udanym uwierzytelnieniu.

<?php
// Wyświetlamy tożsamość
echo $result->getIdentity() . "\n\n";

// Wyświetlamy wiersz rezultatów
print_r($identity);

/* Wyświetlone dane:
my_username

Array
(
    [id] => 1
    [username] => my_username
    [password] => my_password
    [real_name] => My Real Name
)
*/

Z tego względu, że wiersz tabeli zawiera dane potrzebne do uwierzytelniania, ważne jest, aby dane były zabezpieczone przed dostępem przez osoby nieuprawnione.

3.2.2. Zaawansowane użycie: Stałe przechowywanie obiektu DbTable Result

Domyślnie Zend_Auth_Adapter_DbTable po udanym uwierzytelnieniu zwraca do obiektu uwierzytelniającego spowrotem tę samą tożsamość. W innym przykładzie użycia programista może chcieć przechować w stałym mechanizmie przechowywania Zend_Auth obiekt tożsamości zawierający inne użyteczne informacje. W takim przypadku może użyć metody getResultRowObject() aby zwrócić obiekt klasy stdClass. Poniższy kod ilustruje sposób jego użycia:

<?php
// uwierzytelniamy za pomocą Zend_Auth_Adapter_DbTable
$result = $this->_auth->authenticate($adapter);

if ($result->isValid()) {

    // przechowujemy tożsamość jako obiekt, w którym zwracane są jedynie pola username oraz real_name
    $this->_auth->getStorage()->write($adapter->getResultRowObject(array('username', 'real_name'));

    // przechowujemy tożsamość jako obiekt w którym kolumna z hasłem została pominięta
    $this->_auth->getStorage()->write($adapter->getResultRowObject(null, 'password'));

    /* ... */

} else {

    /* ... */

}