In deze tutorial leren we werken met een andere component van het grote Zend Framework, namelijk Zend Auth. Zend Auth laat je toe om een inlog pagina te maken. Er zijn verschillende manieren om Zend Auth te gebruiken maar deze tutorial gaat enkel werken met een MySQL database. We zullen dus een tabel met alle gebruikers nodig hebben en we zullen (hoe kan het ook anders) een formulier moeten maken.
Ik ga werken met de standaard controller (IndexController) en ook de standaard action (IndexAction). Klinken deze termen je onbekend, dan raad ik je aan om de andere Zend Framework tutorials eens te lezen.
Je kan ook zonder het MVC model van Zend Framework Zend Auth gebruiken maar dat raad ik je niet aan omdat we nu eenmaal het complete pakket willen gebruiken.
2. De `user` tabel maken
Omdat we gebruik maken van een database (MySQL) moeten we een tabel hebben om mee te werken. Een `user` tabel bevat altijd dezelfde elementaire elementen, je kan altijd kolomen toevoegen als je dat wilt.
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 50 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL
);
3. De controller
Wat de controller is/doet moet ik je niet meer uitleggen want dat is basiskennis. In de indexAction() maken we onze loginprocedure. De procedure bestaat als volgt:
Ingelogd?
Ja: naar een andere action redirecten (bv welcomeAction())
Nee: is het loginformulier verstuurd?
Ja: de persoon inloggen (*)
Nee: het formulier tonen
(*) Hier komt Zend_Auth aan te pas.
We hebben dus een situatie geschetst, het is tijd om de abstracte codebody te vormen van de controller.
IndexController.php: <?php class IndexController extends Zend_Controller_Action {
public function init() { $this->initView(); }
public function indexAction() {
/** * We slaan de login op in de namespace Zend_Login */ $zend_login = new Zend_Session_Namespace('Zend_Login');
/** * Procedure stap 1: is de gebruiker ingelogged? * $zend_auth->ingelogd is een boolean | true wanneer iemand is ingelogd */ if( $zend_login->ingelogd ) { $this->_redirect('./index/welcome/'); }
/** * Procedure stap 2: is het loginformulier verstuurd? */ if( $this->_request->isPost() ) {
//hier komt Zend_Auth gedeelte
} else {
$this->render();
}
}
public function welcomeAction() {
/** * We slaan de login op in de namespace Zend_Login */ $zend_login = new Zend_Session_Namespace('Zend_Login');
De functies die hier gebruikt worden zijn Helpers (Websites maken met Zend Framework: deel 3/5).
5. De gebruiker inloggen
In puntje 2 van deze tutorial hebben we al de IndexController gemaakt maar niet volledig. Hieronder vind je de volledige code voor de indexAction() voor in de IndexController (de uitleg staat onder de code).
IndexController -> indexAction(): public function indexAction() {
/** * We slaan de login op in de namespace Zend_Login */ $zend_auth = new Zend_Session_Namespace('Zend_Login');
/** * Procedure stap 1: is de gebruiker ingelogged? * $zend_auth->ingelogd is een boolean | true wanneer iemand is ingelogd */ if( $zend_login->ingelogd ) { $this->_redirect('./index/welcome/'); }
/** * Procedure stap 2: is het loginformulier verstuurd? */ if( $this->_request->isPost() ) {
//de database adapter maken Zend_Loader::loadClass('Zend_Db');
//hier komt Zend_Auth gedeelte Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
/** * Maak de Zend_Auth instatie * * @param $db omdat we werken met een database moet Zend_Auth kunnen werken met de database * @param 'users' de tabel waar Zend_Auth moet kijken voor in te loggen * @param 'account' de naam van de kolom waar de gebruikersnaam instaat * @param 'wachtwoord' de naam van de kolom waar het wachtwoord staat. */ $auth = new Zend_Auth_Adapter_DbTable( $db , 'users' , 'username' , 'password' );
//de waarden van het formulier ophalen //alle wachtwoorden zijn MD5 ge-encryped $username = $this->_request->getPost('username'); $password = md5( $this->_request->getPost('password') );
//nu kom Zend_Auth die nu gaat inloggen met de gegevens van hierboven //identity is de kolom waar de username instaat //credential is de kolom waar het wachtwoord instaat $auth->setIdentity($username)->setCredential($password); $result = $auth->authenticate();
//isValid() geeft een object terug bij succes if( $result->isValid() ) {
$username = $result->getIdentity();
//schrijf de login weg in de sessie $zend_login->ingelogd = true; $zend_login->username = $username;
//refresh $this->_redirect('./index/welcome/');
}
} else {
$this->render();
}
}
code uitleg:
- Omdat onze logins in een MySQL tabel staan moeten we een connectie hebben met de database. Zend_Db zorgt hiervoor. Je moet de gegevens aanpassen naar de gegevens van jou MySQL account.
- new Zend_Auth_Adapter_DbTable: dit maakt een object aan zodat je hiermee Zend_Auth kan gebruiken. De adapter zorgt gewoon voor de database dingen die Zend_Auth zal gebruiken bij het uitvoeren van de login. Je kan deze instantie ook op een andere manier schrijven (zie note 1*).
- $auth->setIdentity($username)->setCredential($password): eerst en vooral, deze wijze is correct geschreven hoor. Je moet de waarden van het formulier doorgeven via deze 2 functies van Zend_Auth zodat hij de login procedure kan uitvoeren.
- $result = $auth->authenticate(): dit spreekt eigenlijk voor zich. Deze functie voert gewoon de login query uit. $result zal dan een object bevatten met de resultaten.
- $result->isValid(): $result bevat dus het object met de resultaten en isValid() geeft true of false terug als de login geslaagd is of niet. Je kan de validatie ook anders doen (zie note 2*).
- $username = $result->getIdentity(): getIdentity geeft de username terug (zie ook note 3*).
- Als laatste schrijven we alles weg in de sessie en herladen we de pagina.
5.1. Note 1
Je kan de instantie ook op volgende manier maken. De set functies spreken voor zich.
$authAdapter = new Zend_Auth_Adapter_DbTable($db); $authAdapter->setTableName('users')->setIdentityColumn('username')->setCredentialColumn('password');
5.2. Note 2
Je kan via $result->getCode() ook zien of de login geslaagd is en eventueel de fout aantonen (vb: verkeerde gebruikersnaam e.d.).
switch ( $result->getCode() ) {
case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND: throw new Exception("Login niet geslaagd omdat de gebruikersnaam ongeldig is!"); break;
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID: throw new Exception("Login niet geslaagd omdat het wachtwoord ongeldig is!"); break;
case Zend_Auth_Result::SUCCESS: throw new Exception("Login geslaagd!"); break;
default: throw new Exception("Login niet geslaagd!"); break;
}
Hieronder vind je alle constanten voor $result->getCode()
Wat je ook kan doen is wanneer $result->isValid() false is de berichten tonen waar de fout(en) zaten. $result->getMessages() geeft een array met die foutmeldingen.
if ( ! $result->isValid() ) {
foreach ( $result->getMessages() as $foutmelding ) { echo $foutmelding; }
}
5.3. Note 3
$result->getIdentity() is niet de enige functie waar je waarden van de user kan opvragen. Stel dat je de gebruiker zijn email wilt opslaan in de sessie of een andere kolom wilt opvragen. Via de functie $result->getResultRowObject( array(...) ); kan je kolomen opvragen. Je geeft als parameter een array mee met de namen van de kolommen die je wilt hebben.
Let op: als je 1 kolom wilt opvragen moet je dit ook als array meegeven!
Je hoeft Zend_Session_Namespace niet te gebruiken. Met Zend_Auth kan je een opslag instellen waarin je de gegevens van een gebruiker kan inschrijven. Je maakt eerst de instantie en daarna kan je gegevens aanpassen (schrijven, wissen, ...).
//inlezen, hier zal $readed een object bevatten. $readed = $storage->read(); echo $readed->id; echo $readed->username; echo $readed->email;
$storage = new Zend_Auth_Storage_Session(): deze zal het object teruggeven van de storage. Je kan de naam meegeven van de namespace en de member van de namespace met de constructor.
$storage = new Zend_Auth_Storage_Session( 'gebruiker' , 'informatie' );
De contructor zal dan alles schrijven in de Zend_Session_Namespace('gebruiker')->informatie. Als je niets meegeeft gebruikt hij de standaard waarden. Voor de naam van de Namespace is dit Zend_Auth en voor de member is dit storage. Je kan dan via de read() functie de gegevens terug opvragen of via volgende manier kan ook.
$zend_auth = new Zend_Session_Namespace('Zend_Auth'); $readed = $zend_auth->storage;
LET OP! als je met een eigen Zend_Session_Namespace werkt is het aan te raden om een andere naam dan 'Zend_Auth' te nemen.
7. Tot slot
Je kan nu al heel wat met Zend Framework en zoals je ziet zitten de componenten goed in elkaar. In me laatste tutorial over Zend Framework gaan we dieper in op het framework zelf en gaan we zelfs het framework uitbreiden. O.a. wordt Zend_Auth_Adapter_DbTable aangepast zodat hij enkel users aanvaard die geactiveerd zijn etc.