1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
<com:TContent ID="Main">
<h1>Création de la page <tt>LoginUser</tt></h1>
<p>
La page <tt>LoginUser</tt> affiche un formulaire et gère l'authentification de l'utilisateur. Comme décrit dans <a href="?page=Day3.Auth">authentification et autorisation</a>, le navigateur est automatiquement redirigé vers la page <tt>LoginUser</tt> quand un utilisateur essaye d'accéder à une page protégée, telle que la page d'administration des utilisateurs.
</p>
<p>
Le processus de la page <tt>LoginUser</tt> est similaire à celui de la page <a href="?page=Day1.CreateContact">Contact</a>:
</p>
<ol>
<li>Quand un utilisateur accède à la page <tt>LoginUser</tt>, un formulaire est affiché;</li>
<li>L'utilisateur remplit les champs, nom de l'utilisateur et mot de passe et clique sur le bouton "envoyer";</li>
<li>La classe <tt>LoginUser</tt> reçoit l'évènement "login" et lance la séquence d'authentification;</li>
<li>Si le nom d'utilisateur et le mot de passe sont corrects, le système l'enregistre en session et le redirige vers la page protégée demandée. Dans le cas contraire, un message "mot de passe invalide" est affiché.
</ol>
<p>
Nous créons les deux fichiers <tt>protected/pages/users/LoginUser.page</tt> et <tt>protected/pages/users/LoginUser.php</tt> qui enregistre le gabarit et la classe respectivement.
</p>
<h2>Création du gabarit</h2>
<p>
Ci-après est affiché le gabarit pour <tt>LoginUser</tt>. Comme vous pouvez le constater, la page contient un champ de saisie pour le nom de l'utilisateur et un autre pour le mot de passe. Le nom de l'utilisateur est requis, ce que le validateur <tt>TRequiredFieldValidator</tt> contrôle. La validité du mot de passe est assurée par le validateur <a href="http://www.pradosoft.com/demos/quickstart/index.php?page=Controls.Validation">TCustomValidator</a> qui fait un appel à la méthode <tt>validateUser()</tt> de la classe. La page contient aussi un bouton "envoyer" qui fait un appel à <tt>loginButtonClicked()</tt> quand il est activé.
</p>
<com:TTextHighlighter CssClass="source" Language="prado">
<%@ Title="My Blog - Login" %>
<com:TContent ID="Main">
<h1>Connexion</h1>
<span>Votre nom:</span>
<com:TRequiredFieldValidator
ControlToValidate="Username"
ErrorMessage="Veuillez indiquer votre nom."
Display="Dynamic" />
<br/>
<com:TTextBox ID="Username" />
<br/>
<span>Mot de passe:</span>
<com:TCustomValidator
ControlToValidate="Password"
ErrorMessage="vous avez saisi un mot de passe invalide."
Display="Dynamic"
OnServerValidate="validateUser" />
<br/>
<com:TTextBox ID="Password" TextMode="Password" />
<br/>
<com:TButton Text="Envoyer" OnClick="loginButtonClicked" />
</com:TContent>
</com:TTextHighlighter>
<h2>Création de la classe</h2>
<p>
Tout comme la page <a href="?page=Day1.CreateContact">Contact</a>, la page <tt>LoginUser</tt> a aussi besoin d'un fichier de classe qui implémente les évènements générés dans le fichier gabarit. Ici, nous avons besoin de deux méthodes : <tt>validateUser()</tt> et <tt>loginButtonClicked()</tt>. Dans <tt>validateUser()</tt>, nous utilisons le <a href="?page=Day3.Auth">gestionnaire d'authentification</a> pour vérifier si le nom d'utilisateur et le mot de passe sont valides. Si c'est le cas, le gestionnaire d'authentification créé automatiquement une session utilisateur avec les données correspondantes.
</p>
<com:TTextHighlighter CssClass="source" Language="php">
class LoginUser extends TPage
{
/**
* Vérifie la validité du nom d'utilisateur et du mot de passe.
* Cette méthode implémente l'évènement <tt>OnServerValidate</tt> du validateur <tt>TCustomValidator</tt>.
* @param mixed sender : celui qui a généré l'évènement
* @param mixed param : paramètres de l'évènement
*/
public function validateUser($sender,$param)
{
$authManager=$this->Application->getModule('auth');
if(!$authManager->login($this->Username->Text,$this->Password->Text))
$param->IsValid=false; // indique au validateur que la validation à échoué
}
/**
* Rédirige le navigateur vers l'URL originellement demandée si la validation est Ok.
* Cette méthode implémente l'évènement <tt>OnClick</tt> du bouton "envoyer".
* @param mixed sender : celui qui a généré l'évènement
* @param mixed param : paramètres de l'évènement
*/
public function loginButtonClicked($sender,$param)
{
if($this->Page->IsValid) // toutes les validations sont ok ?
{
// récupère l'URL de la page protégée qui avait été demandée par l'utilisateur
$url=$this->Application->getModule('auth')->ReturnUrl;
if(empty($url)) // l'utilisateur à accéder à la page de connexion directement
$url=$this->Service->DefaultPageUrl;
$this->Response->redirect($url);
}
}
}
</com:TTextHighlighter>
<h2>Test</h2>
<p>
Nous avons donc créé la page <tt>LoginUser</tt>. Nous pouvons la tester en naviguant à l'URL <tt>http://hostname/blog/index.php?page=users.LoginUser</tt>. Rappellez-vous que la dans la section <a href="?page=Day2.CreateDB">Création de la base</a>, nous avons déjà créé deux comptes utilisateurs (nom d'utilisateur/mot de passe) <tt>admin/demo</tt> et <tt>demo/demo</tt>. Nous pouvons donc les utiliser pour tester notre page de connexion.
</p>
<img src="<%~ output.gif %>" class="output"/>
<h2>Ajout des liens de connexion/déconnexion à notre gabarit principal</h2>
<p>
Pour permettre à l'utilisateur d'accéder directement aux pages de connexion/déconnexion, nous modifions le gabarit principal <tt>MainLayout</tt>. En particulier, nous ajoutons un lien vers la page <tt>LoginUser</tt>. Nous ajoutons aussi un lien "se déconnecter" qui permet à l'utilisateur de se déconnecter.
</p>
<p>
Nous modifions le pied de page de notre gabarit principal <tt>MainLayout</tt>. La visibilité des liens vers "se connecter" et "se déconnecter" dépend du statut de l'utilisateur. Si l'utilisateur n'est pas encore connecté, ie: <tt>$this->User->IsGuest</tt> est vrai, alors le lien "se connecter" est visible tandis que le lien "se déconnecter" ne l'est pas et inversement s'il est connecté.
</p>
<com:TTextHighlighter CssClass="source" Language="prado">
<div id="footer">
<com:THyperLink Text="Se connecter"
NavigateUrl="<%= $this->Service->constructUrl('users.LoginUser') %>"
Visible="<%= $this->User->IsGuest %>" />
<com:TLinkButton Text="Se déconnecter"
OnClick="logoutButtonClicked"
Visible="<%= !$this->User->IsGuest %>" />
<br/>
<%= PRADO::poweredByPrado() %>
</div>
</com:TTextHighlighter>
<p>
Vu que le lien "se déconnecter" génère l'évènement <tt>OnClick</tt> avec comme nom d'évènement <tt>logoutButtonClicked()</tt>, nous devons modifier le fichier de classe de <tt>MainLayout</tt> comme ci-dessous :
</p>
<com:TTextHighlighter CssClass="source" Language="php">
class MainLayout extends TTemplateControl
{
/**
* Déconnecte un utilisateur.
* Cette méthode répond à l'évènement OnClick du lien "se déconnecter".
* @param mixed sender : celui qui a généré l'évènement
* @param mixed param : paramètres de l'évènement
*/
public function logoutButtonClicked($sender,$param)
{
$this->Application->getModule('auth')->logout();
$url=$this->Service->constructUrl($this->Service->DefaultPage);
$this->Response->redirect($url);
}
}
</com:TTextHighlighter>
<p>
Maintenant si nous visitons n'importe quelle page de notre blog, nous verrons apparaitre un lien en pied de page. Le lien affiche "se connecter" si nous ne sommes pas connectés et "se déconnecter" dans le cas contraire. Si nous cliquons sur le lien "se déconnecter", nous sommes redirigés vers la page d'accueil et le lien "se connecter" apparait indiquant que nous ne sommes plus connectés.
</p>
</com:TContent>
|