[ZF-10089] Zend_Log
[zend.git] / documentation / manual / pl / module_specs / Zend_Auth_Adapter_DbTable.xml
blobacaa58bf0c37776a7a1335627ad95b001ee18100
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.auth.adapter.dbtable">
4     <title>Uwierzytelnianie w oparciu o tabelę bazy danych</title>
5     <sect2 id="zend.auth.adapter.dbtable.introduction">
6         <title>Wprowadzenie</title>
7         <para>
8             <classname>Zend_Auth_Adapter_DbTable</classname> zapewnia możliwość
9             przeprowadzenia uwierzytelniania w oparciu o dane przechowywane w
10             tabeli bazy danych. Z tego względu, że klasa
11             <classname>Zend_Auth_Adapter_DbTable</classname> wymaga przekazania instancji
12             klasy <classname>Zend_Db_Adapter_Abstract</classname> do jej konstruktora,
13             każda ta instancja jest powiązana z konkretnym połączeniem do bazy
14             danych. Inne opcje konfiguracyjne mogą być ustawione za pomocą
15             konstruktora lub za pomocą metod instancji, po jednej dla każdej z
16             opcji.
17         </para>
19         <para>
20             Dostępne opcje konfiguracyjne to:
21         </para>
23         <itemizedlist>
24             <listitem>
25                 <para>
26                     <emphasis>tableName</emphasis>: Jest to nazwa tabeli bazy
27                     danych, która zawiera dane uwierzytelniania i do której
28                     jest przeprowadzane zapytanie uwierzytelniające.
29                 </para>
30             </listitem>
31             <listitem>
32                 <para>
33                     <emphasis>identityColumn</emphasis>: Jest to nazwa kolumny
34                     tabeli bazy danych, która reprezentuje tożsamość.
35                     Kolumna tożsamości musi zawierać unikalne wartości,
36                     na przykład takie jak nazwa użytkownika czy adres
37                     e-mail.
38                 </para>
39             </listitem>
40             <listitem>
41                 <para>
42                     <emphasis>credentialColumn</emphasis>: Jest to nazwa kolumny
43                     tabeli bazy danych, która reprezentuje wartość
44                     uwierzytelniającą. W prostym schemacie uwierzytelniania
45                     opartym o nazwę tożsamości i hasło, wartość
46                     uwierzytelniająca odpowiada hasłu. Zobacz także opcję
47                     <emphasis>credentialTreatment</emphasis>.
48                 </para>
49             </listitem>
50             <listitem>
51                 <para>
52                     <emphasis>credentialTreatment</emphasis>: W wielu przypadkach,
53                     hasło i inne wrażliwe dane są zszyfrowane, haszowane,
54                     zakodowane lub w inny sposób przetworzone przez
55                     jakąś funkcję lub algorytm. Określając metodę
56                     przerobienia danych, taką jak na przykład
57                     'MD5(?)' czy 'PASSWORD(?)',
58                     programista może użyć konkretnej funkcji SQL na danych
59                     uwierzytelniających. Z tego względu, że te funkcje są
60                     specyficzne dla konkretnych systemów baz danych, zajrzyj
61                     do odpowiednich dokumentacji aby sprawdzić dostępność
62                     takich funkcji dla twojego systemu bazy danych.
63                 </para>
64             </listitem>
65         </itemizedlist>
67         <example id="zend.auth.adapter.dbtable.introduction.example.basic_usage">
68             <title>Podstawowe użycie</title>
69             <para>
70                 Jak wyjaśniono we wprowadzeniu, konstruktor klasy
71                 <classname>Zend_Auth_Adapter_DbTable</classname> wymaga przekazania mu
72                 instancji klasy <classname>Zend_Db_Adapter_Abstract</classname>,
73                 zapewniającej połączenie do bazy danych, z którym powiązana jest
74                 instancja adaptera uwierzytelniania. Na początku powinno być
75                 utworzone połączenie do bazy danych.
76             </para>
78             <para>
79                 Poniższy kod tworzy adapter bazy danych przechowywanej w pamięci,
80                 tworzy prostą strukturę tabeli, a następnie wstawia wiersz, w
81                 oparciu o który przeprowadzimy później zapytanie
82                 uwierzytelniające. Ten przykład wymaga dostępnego rozszerzenia
83                 PDO SQLite:
84             </para>
86             <programlisting language="php"><![CDATA[
87 // Tworzymy połączenie do bazy danych SQLite przechowywanej w pamięci
88 $dbAdapter = new Zend_Db_Adapter_Pdo_Sqlite(array('dbname' =>
89                                                   ':memory:'));
91 // Budujemy zapytanie tworzące prostą tabelę
92 $sqlCreate = 'CREATE TABLE [users] ('
93            . '[id] INTEGER  NOT NULL PRIMARY KEY, '
94            . '[username] VARCHAR(50) UNIQUE NOT NULL, '
95            . '[password] VARCHAR(32) NULL, '
96            . '[real_name] VARCHAR(150) NULL)';
98 // Tworzymy tabelę z danymi uwierzytelniania
99 $dbAdapter->query($sqlCreate);
101 // Budujemy zapytanie wstawiające wiersz, dla którego możemy przeprowadzić
102 // próbę uwierzytelniania
103 $sqlInsert = "INSERT INTO users (username, password, real_name) "
104            . "VALUES ('my_username', 'my_password', 'My Real Name')";
106 // Wstawiamy dane
107 $dbAdapter->query($sqlInsert);
108 ]]></programlisting>
110             <para>
111                 Gdy połączenie do bazy danych oraz dane w tabeli są już
112                 dostępne, możesz utworzyć instancję klasy
113                 <classname>Zend_Auth_Adapter_DbTable</classname>. Opcje konfiguracyjne
114                 mogą być przekazane do konstruktora lub przekazane jako
115                 parametry do metod dostępowych już po utworzeniu instancji:
116             </para>
118             <programlisting language="php"><![CDATA[
119 // Konfigurujemy instancję za pomocą parametrów konstruktora
120 $authAdapter = new Zend_Auth_Adapter_DbTable(
121     $dbAdapter,
122     'users',
123     'username',
124     'password'
127 // ...lub konfigurujemy instancję za pomocą metod dostępowych
128 $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
129 $authAdapter
130     ->setTableName('users')
131     ->setIdentityColumn('username')
132     ->setCredentialColumn('password')
134 ]]></programlisting>
136             <para>
137                 W tym momencie intancja adaptera uwierzytelniania jest gotowa
138                 do przeprowadzenia zapytań uwierzytelniających. W celu
139                 utworzenia zapytania, wejściowe dane uwierzytelniania
140                 są przekazywane do adaptera przed wywołaniem metody
141                 <methodname>authenticate()</methodname>:
142             </para>
144             <programlisting language="php"><![CDATA[
145 // Ustawiamy wartości danych uwierzytelniania (np., z formularza logowania)
146 $authAdapter
147     ->setIdentity('my_username')
148     ->setCredential('my_password');
150 // Przeprowadzamy zapytanie uwierzytelniające, zapisując rezultat
151 $result = $authAdapter->authenticate();
152 ]]></programlisting>
154             <para>
155                 Oprócz możliwości użycia metody <methodname>getIdentity()</methodname>
156                 obiektu rezultatu uwierzytelniania, obiekt
157                 <classname>Zend_Auth_Adapter_DbTable</classname> pozwala także na
158                 odebranie wiersza tabeli po udanym uwierzytelnieniu.
159             </para>
161             <programlisting language="php"><![CDATA[
162 // Wyświetlamy tożsamość
163 echo $result->getIdentity() . "\n\n";
165 // Wyświetlamy wiersz rezultatów
166 print_r($authAdapter->getResultRowObject());
168 /* Wyświetlone dane:
169 my_username
171 Array
173     [id] => 1
174     [username] => my_username
175     [password] => my_password
176     [real_name] => My Real Name
179 ]]></programlisting>
181             <para>
182                 Z tego względu, że wiersz tabeli zawiera dane potrzebne do
183                 uwierzytelniania, ważne jest, aby dane były zabezpieczone przed
184                 dostępem przez osoby nieuprawnione.
185             </para>
187         </example>
188     </sect2>
189     <sect2 id="zend.auth.adapter.dbtable.advanced.storing_result_row">
190         <title>Zaawansowane użycie: Stałe przechowywanie obiektu DbTable Result</title>
191         <para>
192             Domyślnie <classname>Zend_Auth_Adapter_DbTable</classname> po udanym
193             uwierzytelnieniu zwraca do obiektu uwierzytelniającego spowrotem
194             tę samą tożsamość. W innym przykładzie użycia programista może
195             chcieć przechować w stałym mechanizmie przechowywania
196             <classname>Zend_Auth</classname> obiekt tożsamości zawierający inne użyteczne
197             informacje. W takim przypadku może użyć metody
198             <methodname>getResultRowObject()</methodname> aby zwrócić obiekt klasy
199             <classname>stdClass</classname>. Poniższy kod ilustruje sposób jego użycia:
200         </para>
202         <programlisting language="php"><![CDATA[
203 // uwierzytelniamy za pomocą Zend_Auth_Adapter_DbTable
204 $result = $this->_auth->authenticate($adapter);
206 if ($result->isValid()) {
208     // przechowujemy tożsamość jako obiekt, w którym zwracane są jedynie
209     // pola username oraz real_name
210     $storage = $this->_auth->getStorage();
211     $storage->write($adapter->getResultRowObject(array(
212         'username',
213         'real_name'
214     )));
216     // przechowujemy tożsamość jako obiekt, w którym kolumna zawierająca
217     // hasło została pominięta
218     $storage->write($adapter->getResultRowObject(
219         null,
220         'password'
221     ));
223     /* ... */
225 } else {
227     /* ... */
230 ]]></programlisting>
231     </sect2>
232     <sect2 id="zend.auth.adapter.dbtable.advanced.advanced_usage">
233         <title>Przykład zaawansowanego użycia</title>
234         <para>
235             O ile głównym przeznaczeniem komponentu <classname>Zend_Auth</classname> 
236             (i odpowiednio <classname>Zend_Auth_Adapter_DbTable</classname>) jest
237             <emphasis>uwierzytelnianie</emphasis> a nie <emphasis>autoryzacja</emphasis>,
238             jest kilka problemów które możemy rozwiązać odrobinę przekraczając
239             pole zastosowań komponentu. Zależnie od tego jak zdecydujesz
240             wyjaśnić swój problem, czasem może być przydatne rozwiązanie
241             problemu autoryzacji podczas uwierzytelniania.
242         </para>
244         <para>
245             Komponent <classname>Zend_Auth_Adapter_DbTable</classname> posiada 
246             pewien wbudowany mechanizm, który może być użyty do dodania dodatkowych 
247             warunków podczas uwierzytelniania, dzięki czemu można rozwiązać niektóre
248             problemy.
249         </para>
251         <programlisting language="php"><![CDATA[
252 // Wartość pola "status" dla tego konta nie jest równa wartości "compromised"
253 $adapter = new Zend_Auth_Adapter_DbTable(
254     $db,
255     'users',
256     'username',
257     'password',
258     'MD5(?) AND status != "compromised"'
261 // Wartość pola "active" dla tego konta jest równa wartości "TRUE"
262 $adapter = new Zend_Auth_Adapter_DbTable(
263     $db,
264     'users',
265     'username',
266     'password',
267     'MD5(?) AND active = "TRUE"'
269 ]]></programlisting>
271         <para>
272             Innym przykładem może być implementacja mechanizmu saltingu. Jest to
273             technika pozwalająca w znaczny sposób zwiększyć bezpieczeństwo
274             aplikacji. Polega ona na tym, że dołączając do każdego hasła losowy
275             łańcuch znaków spowodujemy, że niemożliwe będzie przeprowadzenie
276             ataku brute force na bazę danych w oparciu o przygotowany słownik.
277         </para>
279         <para>
280             Zaczniemy od zmodyfikowania schematu tabeli bazy danych, aby móc
281             przechowywać nasz łańcuch znaków salt:
282         </para>
284         <programlisting language="php"><![CDATA[
285 $sqlAlter = "ALTER TABLE [users] "
286           . "ADD COLUMN [password_salt] "
287           . "AFTER [password]";
289 $dbAdapter->query($sqlAlter);
290 ]]></programlisting>
292         <para>
293             W prosty sposób wygenerujmy salt dla każdego rejestrującego się
294             użytkownika:
295         </para>
297         <programlisting language="php"><![CDATA[
298 for ($i = 0; $i < 50; $i++)
300     $dynamicSalt .= chr(rand(33, 126));
302 ]]></programlisting>
304         <para>
305             I skonfigurujmy sterownik bazy danych:
306         </para>
308         <programlisting language="php"><![CDATA[
309 $adapter = new Zend_Auth_Adapter_DbTable(
310     $db,
311     'users',
312     'username',
313     'password',
314     "MD5(CONCAT('"
315     . Zend_Registry::get('staticSalt')
316     . "', ?, password_salt))"
318 ]]></programlisting>
319         <note>
320             <para>
321                 Możesz jeszcze zwiększyć bezpieczeństwo używając dodatkowo
322                 statycznego fragmentu łańcucha znaków umieszczonego na stałe
323                 w kodzie aplikacji. W przypadku, gdy atakujący uzyska dostęp
324                 do bazy danych (np. za pomocą ataku <acronym>SQL</acronym> 
325                 injection), a nie będzie miał dostępu do kodu źródłowego, 
326                 hasła wciąż będą dla niego nieprzydatne.
327             </para>
328         </note>
330         <para>
331             Innym sposobem jest użycie metody <methodname>getDbSelect()</methodname> 
332             klasy <classname>Zend_Auth_Adapter_DbTable</classname> po utworzeniu
333             adaptera. Ta metoda zwróci obiekt klasy <classname>Zend_Db_Select</classname>, 
334             który ma być użyty do przeprowadzenia uwierzytalniania. Ważne jest, że
335             ta metoda zawsze zwróci ten sam obiekt, niezależnie od tego czy metoda
336             <methodname>authenticate()</methodname> została wywołana czy nie.
337             Ten obiekt <emphasis>nie będzie</emphasis> posiadał żadnych informacji
338             dotyczących nazwy tożsamości i hasła, ponieważ te dane będą umieszczone
339             tam dopiero w czasie wywołania metody <methodname>authenticate()</methodname>.
340         </para>
342         <para>
343             Przykładem sytuacji w której można by użyć metody getDbSelect() 
344             może być potrzeba sprawdzenia statusu użytkownika, czyli sprawdzenia
345             czy konto użytkownika jest aktywne.
346         </para>
348         <programlisting language="php"><![CDATA[
349 // Kontynuując poprzedni przykład 
350 $adapter = new Zend_Auth_Adapter_DbTable(
351     $db,
352     'users',
353     'username',
354     'password',
355     'MD5(?)'
358 // pobieramy obiekt Zend_Db_Select (przez referencję)
359 $select = $adapter->getDbSelect();
360 $select->where('active = "TRUE"');
362 // uwierytelniamy, z warunkiem users.active = TRUE
363 $adapter->authenticate();
364 ]]></programlisting>
365     </sect2>
366 </sect1>